Class OncRpcClient
- java.lang.Object
-
- org.acplt.oncrpc.OncRpcClient
-
- Direct Known Subclasses:
OncRpcHttpClient
,OncRpcTcpClient
,OncRpcUdpClient
public abstract class OncRpcClient extends java.lang.Object
The abstractOncRpcClient
class is the foundation for protcol-specific ONC/RPC clients. It encapsulates protocol-independent functionality, like port resolving, if no port was specified for the ONC/RPC server to contact. This class also provides the method skeleton, for instance for executing procedure calls.In order to communicate with an ONC/RPC server, you need to create an ONC/RPC client, represented by classes derived from
OncRpcClient
. The most generic way to generate an ONC/RPC client is as follows: usenewOncRpcClient(...)
and specify:- the host (of class InetAddress) where the ONC/RPC server resides,
- the ONC/RPC program number of the server to contact,
- the program's version number,
- and finally the IP protocol to use when talking to the server. This can be
either
OncRpcProtocols.ONCRPC_UDP
orOncRpcProtocols.ONCRPC_TCP
.
The next code snippet shows how to create an ONC/RPC client, which can communicate over UDP/IP with the ONC/RPC server for program number
0x49678
on the same host (by coincidence, this is the program number of the ACPLT/KS protocol).OncRpcClient client; try { client = OncRpcClient.newOncRpcClient( InetAddress.getByName("localhost"), 0x49678, 1, OncRpcProtocols.ONCRPC_UDP); } catch ( OncRpcProgramNotRegisteredException e ) { System.out.println("ONC/RPC program server not found"); System.exit(0); } catch ( OncRpcException e ) { System.out.println("Could not contact portmapper:"); e.printStackTrace(System.out); System.exit(0); } catch ( IOException e ) { System.out.println("Could not contact portmapper:"); e.printStackTrace(System.out); System.exit(0); }
This code snippet also shows exception handling. The most common error you'll see is probably an
OncRpcProgramNotRegisteredException
, in case no such program number is currently registered at the specified host. AnOncRpcProgramNotRegisteredException
is a subclass ofOncRpcException
with a detail ofOncRpcException.RPC_PROGNOTREGISTERED
. In case no ONC/RPC portmapper is available at the specified host, you'll get anOncRpcTimeoutException
instead (which is again a subclass ofOncRpcException
with a detail ofOncRpcException.RPC_TIMEDOUT
). You might also get an IOException when using TCP/IP and the server can not be contacted because it does not accept new connections.Instead of calling
OncRpcClient.newOncRpcClient(...)
you can also directly create objects of classesOncRpcTcpClient
andOncRpcUdpClient
if you know at compile time which kind of IP protocol you will use.With a client proxy in your hands, you can now issue ONC/RPC calls. As a really, really simple example -- did I say "simple example"? -- we start with the famous ONC/RPC ping call. This call sends no parameters and expects no return from an ONC/RPC server. It is just used to check whether a server is still responsive.
System.out.print("pinging server: "); try { client.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } System.out.println("server is alive.");
By definition, the ONC/RPC ping call has program number 0 and expects no parameters and replies with no result. Thus we just specify an empty parameter and result in the form of the static
XdrVoid.XDR_VOID
object, when calling the ping procedure in the server using thecall(...)
method.For more complex and sometimes more useful ONC/RPC calls, you will need to write appropriate ONC/RPC parameter and reply classes. Unfortunately, at this time there's no compiler available to compile
.x
files into appropriate Java classes. Well -- surely a lot of people will now associate completely wrong things with "x files", but in our case there's no new age or whatever mumbo jumbo involved, but definitions of XDR data structures instead. For the next example, let's pretend our server provides the answer to all questions when called with procedure number 42. Let's also pretend that this ONC/RPC call expects a question in form of a string and returns the answer as an integer. So we need to define two classes, one for the call's parameters and one for the reply. But let us first examine the class containing a call's parameters:class Parameters implements XdrAble { public String question; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeString(question); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { question = xdr.xdrDecodeString(); } }
The
Parameters
class implementsXdrAble
, so instances of it can be sent and received over the network using Sun's XDR protocol. What exactly is sent over the wire is up to the two methodsxdrEncode(...)
andxdrDecode(...)
. ThexdrEncode
method is responsible to "encode" the data to be sent over the network. On the other side,xdrDecode
is responsible to restore an object's state from the data received over the network. In our example, these methods either send or receive a string.The class defining the reply of our the-answer-to-all-questions ONC/RPC call is now straightforward:
class Answer implements XdrAble { public int definitiveAnswer; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(definitiveAnswer); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { definitiveAnswer = xdr.xdrDecodeInt(); } }
Finally, to ask a question, you need to create the parameter object and fill it with the parameters to be sent. Then create the object later receiving the reply. Finally issue the ONC/RPC call:
Parameters parameters = new Parameters(); parameters.question = "What is the final answer to all our questions?"; Answer answer = new Answer(); try { client.call(42, parameters, answer); } catch ( OncRpcException e ) { } catch ( IOException e ) { } System.out.println(parameters.question); System.out.println("And the answer is: " + answer.definitiveAnswer);
When you do not need the client proxy object any longer, you should return the resources it occupies to the system. Use the
close()
method for this.client.close(); client = null; // Hint to the garbage (wo)man
Authentication
can be done as follows: just create an authentication object and hand it over to the ONC/RPC client object.OncRpcClientAuth auth = new OncRpcClientAuthUnix( "marvin@ford.prefect", 42, 1001, new int[0]); client.setAuth(auth);
Theauthentication
will handle shorthand credentials (of typeAUTH_UNIX
AUTH_SHORT
) transparently. If you do not set any authentication object after creating an ONC/RPC client object,AUTH_NONE
is used automatically.TCP-based ONC/RPC clients also support call batching (exception handling ommited for clarity):
OncRpcTcpClient client = new OncRpcTcpClient( InetAddress.getByName("localhost"), myprogramnumber, myprogramversion, OncRpcProtocols.ONCRPC_TCP); client.callBatch(42, myparams, false); client.callBatch(42, myotherparams, false); client.callBatch(42, myfinalparams, true);
In the example above, three calls are batched in a row and only be sent all together with the third call. Note that batched calls must not expect replies, with the only exception being the last call in a batch:client.callBatch(42, myparams, false); client.callBatch(42, myotherparams, false); client.call(43, myfinalparams, myfinalresult);
- Version:
- $Revision: 1.3 $ $Date: 2003/08/14 13:48:33 $ $State: Exp $ $Locker: $
- Author:
- Harald Albrecht
- See Also:
OncRpcPortmapClient
,OncRpcTcpClient
,OncRpcUdpClient
,OncRpcClientAuth
-
-
Field Summary
Fields Modifier and Type Field Description protected OncRpcClientAuth
auth
Authentication protocol object to be used when issuing ONC/RPC calls.protected java.net.InetAddress
host
Internet address of the host where the ONC/RPC server we want to communicate with is located at.protected int
port
Port number at which the ONC/RPC server can be contacted.protected int
program
Program number of the ONC/RPC server to communicate with.protected int
timeout
Timeout (in milliseconds) for communication with an ONC/RPC server.protected int
version
Version number of the ONC/RPC server to communicate with.protected int
xid
The message id (also sometimes known as "transaction id") used for the next call message.
-
Constructor Summary
Constructors Modifier Constructor Description protected
OncRpcClient(java.net.InetAddress host, int program, int version, int port, int protocol)
Constructs anOncRpcClient
object (the generic part).
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description abstract void
call(int procedureNumber, int versionNumber, XdrAble parameters, XdrAble result)
Calls a remote procedure on an ONC/RPC server.void
call(int procedureNumber, XdrAble params, XdrAble result)
Calls a remote procedure on an ONC/RPC server.void
close()
Close the connection to an ONC/RPC server and free all network-related resources.OncRpcClientAuth
getAuth()
Returns the current authentication.abstract java.lang.String
getCharacterEncoding()
Get the character encoding for (de-)serializing strings.java.net.InetAddress
getHost()
Returns the IP address of the server's host this client is connected to.int
getPort()
Returns port number of the server this client is connected to.int
getProgram()
Returns the program number specified when creating this client.int
getTimeout()
Retrieve the current timeout set for remote procedure calls.int
getVersion()
Returns the version number specified when creating this client.static OncRpcClient
newOncRpcClient(java.net.InetAddress host, int program, int version, int protocol)
Creates a new ONC/RPC client object, which can handle the requestedprotocol
.static OncRpcClient
newOncRpcClient(java.net.InetAddress host, int program, int version, int port, int protocol)
Creates a new ONC/RPC client object, which can handle the requestedprotocol
.protected void
nextXid()
Create next message identifier.void
setAuth(OncRpcClientAuth auth)
Sets the authentication to be used when making ONC/RPC calls.abstract void
setCharacterEncoding(java.lang.String characterEncoding)
Set the character encoding for (de-)serializing strings.void
setTimeout(int milliseconds)
Set the timout for remote procedure calls to wait for an answer from the ONC/RPC server.
-
-
-
Field Detail
-
host
protected java.net.InetAddress host
Internet address of the host where the ONC/RPC server we want to communicate with is located at.
-
timeout
protected int timeout
Timeout (in milliseconds) for communication with an ONC/RPC server. ONC/RPC calls through thecall(int, XdrAble, XdrAble)
method will throw an exception if no answer from the ONC/RPC server is received within the timeout time span.
-
program
protected int program
Program number of the ONC/RPC server to communicate with.
-
version
protected int version
Version number of the ONC/RPC server to communicate with.
-
port
protected int port
Port number at which the ONC/RPC server can be contacted.
-
xid
protected int xid
The message id (also sometimes known as "transaction id") used for the next call message.
-
auth
protected OncRpcClientAuth auth
Authentication protocol object to be used when issuing ONC/RPC calls.
-
-
Constructor Detail
-
OncRpcClient
protected OncRpcClient(java.net.InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, java.io.IOException
Constructs anOncRpcClient
object (the generic part). If no port number is given (that is,port
is0
), then a port lookup using the portmapper athost
is done.- Parameters:
host
- Host address where the desired ONC/RPC server resides.program
- Program number of the desired ONC/RPC server.version
- Version number of the desired ONC/RPC server.protocol
-Protocol
to be used for ONC/RPC calls. This information is necessary, so port lookups through the portmapper can be done.- Throws:
OncRpcException
- if an ONC/RPC error occurs.java.io.IOException
- if an I/O error occurs.
-
-
Method Detail
-
newOncRpcClient
public static OncRpcClient newOncRpcClient(java.net.InetAddress host, int program, int version, int protocol) throws OncRpcException, java.io.IOException
Creates a new ONC/RPC client object, which can handle the requestedprotocol
.- Parameters:
host
- Host address where the desired ONC/RPC server resides.program
- Program number of the desired ONC/RPC server.version
- Version number of the desired ONC/RPC server.protocol
-Protocol
to be used for ONC/RPC calls.- Throws:
OncRpcException
- if an ONC/RPC error occurs.java.io.IOException
- if an I/O error occurs.
-
newOncRpcClient
public static OncRpcClient newOncRpcClient(java.net.InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, java.io.IOException
Creates a new ONC/RPC client object, which can handle the requestedprotocol
.- Parameters:
host
- Host address where the desired ONC/RPC server resides.program
- Program number of the desired ONC/RPC server.version
- Version number of the desired ONC/RPC server.port
- Port number of the ONC/RPC server. Specifiy0
if this is not known and the portmap process located at host should be contacted to find out the port.protocol
-Protocol
to be used for ONC/RPC calls.- Throws:
OncRpcException
- if an ONC/RPC error occurs.java.io.IOException
- if an I/O error occurs.
-
close
public void close() throws OncRpcException
Close the connection to an ONC/RPC server and free all network-related resources. Well -- at least hope, that the Java VM will sometimes free some resources. Sigh.- Throws:
OncRpcException
- if an ONC/RPC error occurs.
-
call
public void call(int procedureNumber, XdrAble params, XdrAble result) throws OncRpcException
Calls a remote procedure on an ONC/RPC server.The
OncRpcUdpClient
uses a similar timeout scheme as the genuine Sun C implementation of ONC/RPC: it starts with a timeout of one second when waiting for a reply. If no reply is received within this time frame, the client doubles the timeout, sends a new request and then waits again for a reply. In every case the client will wait no longer than the total timeout set through thesetTimeout(int)
method.- Parameters:
procedureNumber
- Procedure number of the procedure to call.params
- The parameters of the procedure to call, contained in an object which implements theXdrAble
interface.result
- The object receiving the result of the procedure call.- Throws:
OncRpcException
- if an ONC/RPC error occurs.
-
call
public abstract void call(int procedureNumber, int versionNumber, XdrAble parameters, XdrAble result) throws OncRpcException
Calls a remote procedure on an ONC/RPC server.- Parameters:
procedureNumber
- Procedure number of the procedure to call.versionNumber
- Protocol version number.parameters
- The parameters of the procedure to call, contained in an object which implements theXdrAble
interface.result
- The object receiving the result of the procedure call.- Throws:
OncRpcException
- if an ONC/RPC error occurs.
-
setTimeout
public void setTimeout(int milliseconds)
Set the timout for remote procedure calls to wait for an answer from the ONC/RPC server. If the timeout expires,call(int, XdrAble, XdrAble)
will raise aInterruptedIOException
. The default timeout value is 30 seconds (30,000 milliseconds). The timeout must be > 0. A timeout of zero indicated batched calls, for which no reply message is expected.- Parameters:
milliseconds
- Timeout in milliseconds. A timeout of zero indicates batched calls.
-
getTimeout
public int getTimeout()
Retrieve the current timeout set for remote procedure calls. A timeout of zero indicates batching calls (no reply message is expected).- Returns:
- Current timeout.
-
getProgram
public int getProgram()
Returns the program number specified when creating this client.- Returns:
- ONC/RPC program number.
-
getVersion
public int getVersion()
Returns the version number specified when creating this client.- Returns:
- ONC/RPC version number of ONC/RPC program.
-
getHost
public java.net.InetAddress getHost()
Returns the IP address of the server's host this client is connected to.- Returns:
- IP address of host.
-
getPort
public int getPort()
Returns port number of the server this client is connected to.- Returns:
- port number of ONC/RPC server.
-
setAuth
public void setAuth(OncRpcClientAuth auth)
Sets the authentication to be used when making ONC/RPC calls.- Parameters:
auth
- Authentication protocol handling object encapsulating authentication information.
-
getAuth
public OncRpcClientAuth getAuth()
Returns the current authentication.- Returns:
- Authentication protocol handling object encapsulating authentication information.
-
setCharacterEncoding
public abstract void setCharacterEncoding(java.lang.String characterEncoding)
Set the character encoding for (de-)serializing strings.- Parameters:
characterEncoding
- the encoding to use for (de-)serializing strings. Ifnull
, the system's default encoding is to be used.
-
getCharacterEncoding
public abstract java.lang.String getCharacterEncoding()
Get the character encoding for (de-)serializing strings.- Returns:
- the encoding currently used for (de-)serializing strings.
If
null
, then the system's default encoding is used.
-
nextXid
protected void nextXid()
Create next message identifier. Message identifiers are used to match corresponding ONC/RPC call and reply messages.
-
-