|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.acplt.oncrpc.OncRpcClient
public abstract class OncRpcClient
The abstract OncRpcClient
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: use
newOncRpcClient(...)
and specify:
OncRpcProtocols.ONCRPC_UDP
or
OncRpcProtocols.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.
An OncRpcProgramNotRegisteredException
is a subclass of
OncRpcException
with a detail of
OncRpcException.RPC_PROGNOTREGISTERED
.
In case no ONC/RPC portmapper is available at the specified host, you'll
get an OncRpcTimeoutException
instead (which is again a subclass of
OncRpcException
with a detail of
OncRpcException.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 classes
OncRpcTcpClient
and OncRpcUdpClient
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 the
call(...)
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 implements XdrAble
, 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 methods
xdrEncode(...)
and
xdrDecode(...)
. The xdrEncode
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);The
authentication AUTH_UNIX
will
handle shorthand credentials (of type 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);
OncRpcPortmapClient
,
OncRpcTcpClient
,
OncRpcUdpClient
,
OncRpcClientAuth
Field Summary | |
---|---|
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 | |
---|---|
protected |
OncRpcClient(java.net.InetAddress host,
int program,
int version,
int port,
int protocol)
Constructs an OncRpcClient object (the generic part). |
Method Summary | |
---|---|
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 requested protocol . |
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 requested protocol . |
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. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
protected java.net.InetAddress host
protected int timeout
call(int, XdrAble, XdrAble)
method
will throw an exception if no answer from the ONC/RPC server is
received within the timeout time span.
protected int program
protected int version
protected int port
protected int xid
protected OncRpcClientAuth auth
Constructor Detail |
---|
protected OncRpcClient(java.net.InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, java.io.IOException
OncRpcClient
object (the generic part). If
no port number is given (that is, port
is 0
),
then a port lookup using the portmapper at host
is done.
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.
OncRpcException
- if an ONC/RPC error occurs.
java.io.IOException
- if an I/O error occurs.Method Detail |
---|
public static OncRpcClient newOncRpcClient(java.net.InetAddress host, int program, int version, int protocol) throws OncRpcException, java.io.IOException
protocol
.
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.
OncRpcException
- if an ONC/RPC error occurs.
java.io.IOException
- if an I/O error occurs.public static OncRpcClient newOncRpcClient(java.net.InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, java.io.IOException
protocol
.
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. Specifiy 0
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.
OncRpcException
- if an ONC/RPC error occurs.
java.io.IOException
- if an I/O error occurs.public void close() throws OncRpcException
OncRpcException
- if an ONC/RPC error occurs.public void call(int procedureNumber, XdrAble params, XdrAble result) throws OncRpcException
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 the
setTimeout(int)
method.
procedureNumber
- Procedure number of the procedure to call.params
- The parameters of the procedure to call, contained
in an object which implements the XdrAble
interface.result
- The object receiving the result of the procedure call.
OncRpcException
- if an ONC/RPC error occurs.public abstract void call(int procedureNumber, int versionNumber, XdrAble parameters, XdrAble result) throws OncRpcException
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 the XdrAble
interface.result
- The object receiving the result of the procedure call.
OncRpcException
- if an ONC/RPC error occurs.public void setTimeout(int milliseconds)
call(int, XdrAble, XdrAble)
will raise a
InterruptedIOException
. 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.
milliseconds
- Timeout in milliseconds. A timeout of zero indicates
batched calls.public int getTimeout()
public int getProgram()
public int getVersion()
public java.net.InetAddress getHost()
public int getPort()
public void setAuth(OncRpcClientAuth auth)
auth
- Authentication protocol handling object encapsulating
authentication information.public OncRpcClientAuth getAuth()
public abstract void setCharacterEncoding(java.lang.String characterEncoding)
characterEncoding
- the encoding to use for (de-)serializing strings.
If null
, the system's default encoding is to be used.public abstract java.lang.String getCharacterEncoding()
null
, then the system's default encoding is used.protected void nextXid()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |