[OpenDHT-Users] Fwd: Java, XML RPC and OpenDHT!
Sean Rhea
srhea@MIT.EDU
Mon, 1 May 2006 10:36:52 -0400
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--Apple-Mail-47-683288933
Content-Type: multipart/mixed; boundary=Apple-Mail-46-683288446
--Apple-Mail-46-683288446
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed
This should be interesting to those of you trying to use OpenDHT via
Apache's XML RPC client.
Sean
Begin forwarded message:
> From: "Ryan Worsley" <ryanthemadone@hotmail.com>
> Date: April 27, 2006 7:29:32 PM EDT
> To: <srhea@mit.edu>
> Subject: Java, XML RPC and OpenDHT!
>
> Sean,
>
>
> Hi, we haven't met or spoken much before. You helped me try and
> debug some problems I was having using OpenDHT.
>
>
> Recently I've received several enquiries from people who are
> attempting to use Apache's XML RPC and Java to access OpenDHT.
> This is something I have largely gotten to work. I still have a
> bug when doing remove operations, but my dissertation was due in
> today so I can hopefully figure out what the hey is going on there.
>
>
> Anyway I've attached a copy of my OpenDHT gateway class. This is
> all I'm sending out to people who have enquiries about how to write
> Java OpenDHT apps. I figured you might find it useful or might
> like to rewrite it so that it isn't terrible code.
>
>
> Cheers for building a great network by the way, my dissertation
> depended on it!
>
>
> Regards,
>
>
> Ryan Worsley.
>
> University of Sussex.
--Apple-Mail-46-683288446
Content-Transfer-Encoding: quoted-printable
Content-Type: application/octet-stream;
x-unix-mode=0666;
name="OpenDHTGateway.java"
Content-Disposition: attachment;
filename=OpenDHTGateway.java
package=20DHT;=0D=0Aimport=20java.io.*;=0D=0Aimport=20java.net.*;=0D=0A=
import=20java.security.*;=0D=0Aimport=20java.util.*;=0D=0Aimport=20=
org.apache.xmlrpc.*;=0D=0A=0D=0A/**=0D=0A=20*=20This=20class=20provides=20=
transparent=20access=20to=20the=20OpenDHT=20network=0D=0A=20*=20by=20=
using=20the=20Apache=20XML=20RPC=20package=20for=20Java.=20=20This=20=
class=20makes=0D=0A=20*=20it=20easy=20to=20perform=20get=20and=20put=20=
operations=20on=20the=20DHT.=0D=0A=20*=20=0D=0A=20*=20@author=20Ryan=20=
Worsley=0D=0A=20*=20@version=201.6=0D=0A=20*/=0D=0Apublic=20class=20=
OpenDHTGateway=20{=0D=0A=09private=20InetAddress=20bootstrapNode;=0D=0A=09=
private=20XmlRpcClient=20rpc;=0D=0A=09private=20MessageDigest=20sha;=0D=0A=
=09private=20boolean=20connected=20=3D=20false;;=0D=0A=09=0D=0A=09/**=0D=0A=
=09=20*=20Construct=20a=20new=20gateway.=0D=0A=09=20*=0D=0A=09=20*/=0D=0A=
=09public=20OpenDHTGateway()=20{=0D=0A=09=09try=20{=0D=0A=09=09=09sha=20=
=3D=20MessageDigest.getInstance("SHA");=09=09=0D=0A=09=09}=20catch=20=
(NoSuchAlgorithmException=20e)=20{}=0D=0A=09}=0D=0A=09=0D=0A=09/**=0D=0A=09=
=20*=20Construct=20a=20new=20gateway=20and=20optionally=20connect=20to=20=
the=0D=0A=09=20*=20OpenDHT=20network.=0D=0A=09=20*=20=0D=0A=09=20*=20=
@param=20connect=20True=20if=20you=20wish=20to=20connect.=0D=0A=09=20*/=0D=
=0A=09public=20OpenDHTGateway(boolean=20connect)=20{=0D=0A=09=09try=20{=0D=
=0A=09=09=09sha=20=3D=20MessageDigest.getInstance("SHA");=0D=0A=09=09}=20=
catch=20(NoSuchAlgorithmException=20e)=20{}=0D=0A=09=09=0D=0A=09=09if=20=
(connect)=20{=0D=0A=09=09=09connect();=0D=0A=09=09}=0D=0A=09}=0D=0A=09=0D=
=0A=09/**=0D=0A=09=20*=20Put=20something=20in=20the=20DHT.=0D=0A=09=20*=20=
=0D=0A=09=20*=20@param=20key=20A=20byte=20array=20for=20the=20key=20in=20=
this=20hash=20table.=0D=0A=09=20*=20@param=20value=20A=20byte=20array=20=
for=20the=20value=20to=20be=20stored.=0D=0A=09=20*=20@param=20ttl=20A=20=
time=20to=20live=20for=20the=20entry=20in=20seconds.=0D=0A=09=20*=20=
@param=20appName=20The=20name=20of=20the=20application=20doing=20the=20=
put.=0D=0A=09=20*=20@return=200=20for=20success,=201=20for=20over=20=
capacity=20and=202=20for=20try=20again.=0D=0A=09=20*/=0D=0A=09public=20=
int=20put(byte[]=20key,=20byte[]=20value,=20int=20ttl,=20String=20=
appName)=20{=0D=0A=09=09Vector=20params=20=3D=20new=20Vector();=0D=0A=09=09=
params.add(key);=0D=0A=09=09params.add(value);=0D=0A=09=09=
params.add(ttl);=0D=0A=09=09params.add(appName);=0D=0A=09=09=0D=0A=09=09=
try=20{=0D=0A=09=09=09Object=20result=20=3D=20rpc.execute("put",=20=
params);=0D=0A=09=09=09if=20(result=20instanceof=20Integer)=20{=0D=0A=09=09=
=09=09return=20(Integer)=20result;=0D=0A=09=09=09}=20else=20if=20(result=20=
instanceof=20XmlRpcException)=20{=0D=0A=09=09=09=09((XmlRpcException)=20=
result).printStackTrace();=0D=0A=09=09=09}=0D=0A=09=09}=20catch=20=
(XmlRpcException=20e)=20{=0D=0A=09=09=09e.printStackTrace();=0D=0A=09=09=
}=20catch=20(IOException=20e)=20{}=0D=0A=09=09return=20-1;=0D=0A=09}=0D=0A=
=09=0D=0A=09/**=0D=0A=09=20*=20Put=20a=20removable=20something=20in=20=
the=20DHT.=0D=0A=09=20*=20=0D=0A=09=20*=20@param=20key=20A=20byte=20=
array=20for=20the=20key=20in=20this=20hash=20table.=0D=0A=09=20*=20=
@param=20value=20A=20byte=20array=20for=20the=20value=20to=20be=20=
stored.=0D=0A=09=20*=20@param=20algorithm=20The=20algorithm=20for=20the=20=
secret=20string.=0D=0A=09=20*=20@param=20secretHash=20The=20secret=20=
hash=20to=20be=20used=20for=20removes.=0D=0A=09=20*=20@param=20ttl=20A=20=
time=20to=20live=20for=20the=20entry=20in=20seconds.=0D=0A=09=20*=20=
@param=20appName=20The=20name=20of=20the=20application=20doing=20the=20=
put.=0D=0A=09=20*=20@return=200=20for=20success,=201=20for=20over=20=
capacity=20and=202=20for=20try=20again.=0D=0A=09=20*/=0D=0A=09public=20=
int=20put_removable(byte[]=20key,=20byte[]=20value,=20String=20=
algorithm,=20byte[]=20secretHash,=20int=20ttl,=20String=20appName)=20{=0D=
=0A=09=09Vector=20params=20=3D=20new=20Vector();=0D=0A=09=09=
params.add(key);=0D=0A=09=09params.add(value);=0D=0A=09=09=
params.add(algorithm);=0D=0A=09=09params.add(secretHash);=0D=0A=09=09=
params.add(ttl);=0D=0A=09=09params.add(appName);=0D=0A=09=09=0D=0A=09=09=
try=20{=0D=0A=09=09=09Object=20result=20=3D=20=
rpc.execute("put_removable",=20params);=0D=0A=09=09=09if=20(result=20=
instanceof=20Integer)=20{=0D=0A=09=09=09=09return=20(Integer)=20result;=0D=
=0A=09=09=09}=20else=20if=20(result=20instanceof=20XmlRpcException)=20{=0D=
=0A=09=09=09=09((XmlRpcException)=20result).printStackTrace();=0D=0A=09=09=
=09}=0D=0A=09=09}=20catch=20(XmlRpcException=20e)=20{=0D=0A=09=09=09=
e.printStackTrace();=0D=0A=09=09}=20catch=20(IOException=20e)=20{}=0D=0A=09=
=09return=20-1;=0D=0A=09}=0D=0A=09=0D=0A=09/**=0D=0A=09=20*=20Gets=20a=20=
key's=20values=20from=20the=20DHT.=0D=0A=09=20*=20=0D=0A=09=20*=20@param=20=
key=20The=20key=20to=20lookup.=0D=0A=09=20*=20@param=20maxvals=20The=20=
maximum=20number=20of=20entries=20to=20return=20under=20this=20key.=0D=0A=
=09=20*=20@param=20placemark=20A=20returned=20placemark=20that=20OpenDHT=20=
uses=20to=20find=20the=20next=20entry.=0D=0A=09=20*=20@param=20appName=20=
The=20name=20of=20the=20application=20doing=20the=20get.=0D=0A=09=20*=20=
@return=20An=20object=20containing=20returned=20values,=20normally=20a=20=
vector.=0D=0A=09=20*/=0D=0A=09public=20Object=20get(byte[]=20key,=20int=20=
maxvals,=20byte[]=20placemark,=20String=20appName)=20{=0D=0A=09=09Vector=20=
params=20=3D=20new=20Vector();=0D=0A=09=09params.add(key);=0D=0A=09=09=
params.add(maxvals);=0D=0A=09=09params.add(placemark);=0D=0A=09=09=
params.add(appName);=0D=0A=09=09=0D=0A=09=09try=20{=0D=0A=09=09=09Object=20=
result=20=3D=20rpc.execute("get",=20params);=0D=0A=09=09=09if=20(result=20=
instanceof=20XmlRpcException)=20{=0D=0A=09=09=09=09((XmlRpcException)=20=
result).printStackTrace();=0D=0A=09=09=09}=20else=20{=0D=0A=09=09=09=09=
return=20result;=0D=0A=09=09=09}=0D=0A=09=09}=20catch=20(XmlRpcException=20=
e)=20{=0D=0A=09=09=09e.printStackTrace();=0D=0A=09=09}=20catch=20=
(IOException=20e)=20{}=0D=0A=09=09return=20null;=0D=0A=09}=0D=0A=09=0D=0A=
=09/**=0D=0A=09=20*=20Method=20to=20remove=20a=20key-value-secretHash=20=
tuple=20from=20the=20DHT.=0D=0A=09=20*=20=0D=0A=09=20*=20@param=20key=20=
The=20key=20to=20remove.=0D=0A=09=20*=20@param=20value=20The=20value=20=
to=20remove.=0D=0A=09=20*=20@param=20algorithm=20The=20algorithm=20to=20=
use=20with=20the=20secret=20hash.=0D=0A=09=20*=20@param=20secret=20The=20=
original=20secret=20to=20be=20hashed=20and=20matched.=0D=0A=09=20*=20=
@param=20ttl=20The=20time=20to=20live=20for=20this=20operation.=0D=0A=09=20=
*=20@param=20appName=20The=20name=20of=20the=20application=20doing=20the=20=
remove.=0D=0A=09=20*=20@return=200=20for=20success,=201=20for=20over=20=
capacity=20and=202=20for=20try=20again.=0D=0A=09=20*/=0D=0A=09public=20=
int=20rm(byte[]=20key,=20byte[]=20value,=20String=20algorithm,=20byte[]=20=
secret,=20int=20ttl,=20String=20appName)=20{=0D=0A=09=09Vector=20params=20=
=3D=20new=20Vector();=0D=0A=09=09params.add(key);=0D=0A=09=09=
params.add(value);=0D=0A=09=09params.add(algorithm);=0D=0A=09=09=
params.add(secret);=0D=0A=09=09params.add(ttl);=0D=0A=09=09=
params.add(appName);=0D=0A=09=09=0D=0A=09=09try=20{=0D=0A=09=09=09Object=20=
result=20=3D=20rpc.execute("rm",=20params);=0D=0A=09=09=09if=20(result=20=
instanceof=20Integer)=20{=0D=0A=09=09=09=09return=20(Integer)=20result;=0D=
=0A=09=09=09}=20else=20if=20(result=20instanceof=20XmlRpcException)=20{=0D=
=0A=09=09=09=09((XmlRpcException)=20result).printStackTrace();=0D=0A=09=09=
=09}=0D=0A=09=09}=20catch=20(XmlRpcException=20e)=20{=0D=0A=09=09=09=
e.printStackTrace();=0D=0A=09=09}=20catch=20(IOException=20e)=20{=0D=0A=09=
=09=09e.printStackTrace();=0D=0A=09=09}=0D=0A=09=09return=20-1;=0D=0A=09=
}=0D=0A=09=0D=0A=09/**=0D=0A=09=20*=20Attempt=20to=20locate=20nodes=20=
and=20connect=20to=20the=20network.=0D=0A=09=20*=20=0D=0A=09=20*=20=
@return=20True=20if=20connection=20successful.=0D=0A=09=20*/=0D=0A=09=
public=20boolean=20connect()=20{=0D=0A=09=09try=20{=0D=0A=09=09=09if=20=
(fileStrap())=20{=0D=0A=09=09=09=09rpc=20=3D=20new=20=
XmlRpcClient(bootstrapNode.getHostName(),=205851);=0D=0A=09=09=09=09=
return=20(connected=20=3D=20true);=0D=0A=09=09=09}=0D=0A=09=09=09return=20=
false;=0D=0A=09=09}=20catch=20(MalformedURLException=20e)=20{=0D=0A=09=09=
=09return=20false;=0D=0A=09=09}=0D=0A=09}=0D=0A=09=0D=0A=09/**=0D=0A=09=20=
*=20Returns=20the=20status=20of=20this=20connection.=0D=0A=09=20*=20=0D=0A=
=09=20*=20@return=20True=20if=20connected.=0D=0A=09=20*/=0D=0A=09public=20=
boolean=20isConnected()=20{=0D=0A=09=09return=20connected;=0D=0A=09}=0D=0A=
=09=0D=0A=09/**=0D=0A=09=20*=20Performs=20an=20SHA=20digest=20on=20the=20=
supplied=20message.=0D=0A=09=20*=20=0D=0A=09=20*=20@param=20message=20=
The=20message=20to=20be=20digested.=0D=0A=09=20*=20@return=20A=20byte=20=
array=20containing=20the=20digested=20message.=0D=0A=09=20*/=0D=0A=09=
public=20byte[]=20shaDigest(String=20message)=20{=0D=0A=09=09=
sha.update(message.getBytes());=0D=0A=09=09byte[]=20digested=20=3D=20=
sha.digest();=0D=0A=09=09sha.reset();=0D=0A=09=09return=20digested;=0D=0A=
=09}=0D=0A=09=0D=0A=09/**=0D=0A=09=20*=20Attempts=20to=20connect=20to=20=
the=20network=20by=20opening=20a=20list=20of=20known=0D=0A=09=20*=20=
nodes=20and=20connecting=20to=20those=20in=20a=20random=20way.=0D=0A=09=20=
*=20=0D=0A=09=20*=20@return=20True=20if=20connection=20successful.=0D=0A=09=
=20*/=0D=0A=09private=20boolean=20fileStrap()=20{=0D=0A=09=09Resource=20=
resource;=0D=0A=09=09Random=20gen=20=3D=20new=20Random();=0D=0A=09=09try=20=
{=0D=0A=09=09=09URL=20location=20=3D=20new=20=
URL("http://www.opendht.org/servers.txt");=0D=0A=09=09=09=
if(Resource.isReachable(location))=20{=0D=0A=09=09=09=09resource=20=3D=20=
Resource.factory(location);=0D=0A=09=09=09}=20else=20{=0D=0A=09=09=09=09=
return=20false;=0D=0A=09=09=09}=0D=0A=09=09=09Vector<String>=20=
candidates=20=3D=20resource.getData();=0D=0A=09=09=09while=20=
(candidates.size()=20>=200)=20{=0D=0A=09=09=09=09String=20current=20=3D=20=
candidates.remove(gen.nextInt(candidates.size()));=0D=0A=09=09=09=09=
bootstrapNode=20=3D=20InetAddress.getByName(current.split("\\s")[2]);=0D=0A=
=09=09=09=09System.out.println("Attempting=20to=20bootstrap=20to=20"=20+=20=
bootstrapNode.getHostName());=0D=0A=09=09=09=09if=20=
(isReachable(bootstrapNode))=20{=0D=0A=09=09=09=09=09=
System.out.println("Reachable=20node=20found.");=0D=0A=09=09=09=09=09=
return=20true;=0D=0A=09=09=09=09}=0D=0A=09=09=09}=0D=0A=09=09}=20catch=20=
(MalformedURLException=20e)=20{=0D=0A=09=09}=20catch=20(IOException=20e)=20=
{}=0D=0A=09=09return=20false;=0D=0A=09}=0D=0A=09=0D=0A=09/**=0D=0A=09=20=
*=20Attempts=20to=20find=20the=20nearest=20node=20by=20performing=20a=20=
DNS=0D=0A=09=20*=20lookup=20on=20a=20special=20address.=0D=0A=09=20*=20=0D=
=0A=09=20*=20@return=20True=20if=20connection=20successful.=0D=0A=09=20=
*/=0D=0A=09private=20boolean=20lookupStrap()=20{=0D=0A=09=09boolean=20=
found=20=3D=20false;=0D=0A=09=09try=20{=0D=0A=09=09=09for=20(int=20i=20=3D=
=200;=20i=20<=2025=20&&=20!found;=20i++)=20{=0D=0A=09=09=09=09=
bootstrapNode=20=3D=20InetAddress.getByName("opendht.nyuld.net");=0D=0A=09=
=09=09=09System.out.println("Attempting=20to=20bootstrap=20to=20"=20+=20=
bootstrapNode.getHostName());=0D=0A=09=09=09=09if=20=
(isReachable(bootstrapNode))=20{=0D=0A=09=09=09=09=09=
System.out.println("Reachable=20node=20found.");=0D=0A=09=09=09=09=09=
found=20=3D=20true;=0D=0A=09=09=09=09}=0D=0A=09=09=09}=0D=0A=09=09}=20=
catch=20(UnknownHostException=20e)=20{=0D=0A=09=09=09=
System.out.println("Host=20unknown.");=0D=0A=09=09}=0D=0A=09=09return=20=
found;=0D=0A=09}=0D=0A=09=0D=0A=09/**=0D=0A=09=20*=20Returns=20true=20if=20=
this=20node=20can=20contact=20the=20specified=20node.=0D=0A=09=20*=20=0D=0A=
=09=20*=20@param=20address=20The=20node=20to=20contact.=0D=0A=09=20*=20=
@return=20True=20if=20this=20node=20can=20reach=20the=20target=20node.=0D=
=0A=09=20*/=0D=0A=09private=20static=20boolean=20isReachable(InetAddress=20=
address)=20{=0D=0A=09=09try=20{=0D=0A=09=09=09=
if(address.isReachable(5000))=20{=0D=0A=09=09=09=09return=20true;=0D=0A=09=
=09=09}=0D=0A=09=09}=20catch=20(MalformedURLException=20e)=20{=0D=0A=09=09=
}=20catch=20(IOException=20e)=20{}=0D=0A=09=09return=20false;=0D=0A=09}=0D=
=0A}=0D=0A=
--Apple-Mail-46-683288446
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
--
An atheist doesn't have to be someone who thinks he has a
proof that there can't be a god. He only has to be someone
who believes that the evidence on the God question is at a
similar level to the evidence on the were-wolf question.
-- John McCarthy
--Apple-Mail-46-683288446--
--Apple-Mail-47-683288933
content-type: application/pgp-signature; x-mac-type=70674453;
name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)
iD8DBQFEVh0KzBwMl0DQ21gRAjzCAJ40cXR9bTT5v4wqakvzeStkSGrRewCdGJgl
V/pxfp+hS1U56iZCMprtWAE=
=HT/4
-----END PGP SIGNATURE-----
--Apple-Mail-47-683288933--