CS 696 Emerging Technologies: Java Distributed Computing Spring Semester, 1999 Client-side Proxies |
||
---|---|---|
© 1999, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 05-Apr-99 |
Server & Proxies
Note the presentation of Server Proxies follows very closely to the Simple example in Jan Newmarch’s Jini Tutorial at: http://pandonia.canberra.edu.au/java/jini/tutorial/Jini.xml. The server provides a different service in this example. A few other details relating to RMI usage and registration are also changed. It is instructive to look at both examples.
In designing a Jini service there are several different strategies:
Client-side proxy – Using RMI
This is easier to do than creating your own proxy object. Most of the examples up to this point have done this. See for instance the hello world example at: http://www.eli.sdsu.edu/courses/spring99/cs696/notes/jiniHello/jiniHello.html .
Client-side proxy – Creating A Proxy by Hand
There are a number of reasons for doing this:
Example
Will use the same example (an encryption server) that was used in Doc 20 (See http://www.eli.sdsu.edu/courses/spring99/cs696/notes/client-side/client-side.html#Heading3).
The classes:
EncryptionInterface
package whitney.jini.examples.serverProxy; import java.rmi.RemoteException; public interface EncryptionInterface { public String[] encodeTypes() throws RemoteException; public String encode( String encodeType, String plainText ) throws RemoteException; public String decode( String encodeType, String encodedText) throws RemoteException; }DirectEncryptionClient
package whitney.jini.examples.serverProxy; import java.rmi.RMISecurityManager; import net.jini.core.discovery.LookupLocator; import net.jini.core.entry.Entry; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.lookup.ServiceTemplate; import net.jini.lookup.entry.Name; public class DirectEncryptionClient { public static void main (String[] args) throws Exception { System.setSecurityManager (new RMISecurityManager ()); LookupLocator lookup = new LookupLocator ("jini://eli.sdsu.edu"); ServiceRegistrar registrar = lookup.getRegistrar (); Entry[] serverAttributes = new Entry[1]; serverAttributes[0] = new Name ("EncryptionService"); ServiceTemplate template = new ServiceTemplate (null, null, serverAttributes); EncryptionInterface encoder = (EncryptionInterface) registrar.lookup (template); String testText = "Hi Mom"; String encodedText = encoder.encode( "xor", testText ); String decodedText = encoder.decode( "xor", encodedText ); System.out.println ( "Original Text: " + testText ); System.out.println ( "Encoded Text: " + encodedText ); System.out.println ( "Decoded Text: " + decodedText ); } }
Encrypter
package whitney.jini.examples.serverProxy; import java.io.Serializable; import sdsu.io.XorOutputStream; import sdsu.io.XorOutputStream; public class Encrypter implements EncryptionInterface { private static final String XOR = "xor"; private byte mask; private String[] encodeTypes = { XOR }; public Encrypter( byte aMask ) { mask = aMask; } public String[] encodeTypes() { return encodeTypes; } public String encode( String encodeType, String plainText ) { if ( encodeType.equals( XOR) ) return xorText( plainText ); else // just an example. Save space by not using exception return ""; } public String decode( String encodeType, String encodedText) { if ( encodeType.equals( XOR) ) return xorText( encodedText ); else // just an example. Save space by not using exception return ""; } private String xorText(String text) { byte inputBytes[] = text.getBytes(); byte[] xorBytes = new byte[inputBytes.length]; for (int k = 0; k < inputBytes.length;k++) xorBytes[k ] =(byte) (inputBytes[k] ^ mask); return new String(xorBytes); } }
TCPEncryptionServer
TCPEncryptionServer Continued package whitney.jini.examples.serverProxy; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import sdsu.io.SimpleReader; import sdsu.util.LabeledData; public class TCPEncryptionServer extends Thread { private int serverPort; DirectEncryptionServer encrypter; static final String COMMAND = "command"; static final String ENCODE = "encode"; static final String DECODE = "decode"; static final String GET_TYPES = "types"; static final String ERROR = "error"; static final String DATA = "data"; static final String CODE_TYPE = "codeType"; static final char END_OF_MESSAGE = '\u000C'; public TCPEncryptionServer( int port, byte mask) { serverPort = port; encrypter = new DirectEncryptionServer( mask); } public void run() { try { ServerSocket acceptor = new ServerSocket( serverPort ); while (true) { Socket client = acceptor.accept(); processClientRequest(client.getInputStream(), client.getOutputStream()); client.close(); } } catch (IOException startup) { System.err.println( "Socket error: " + startup); } }
TCPEncryptionServer Continued public void processClientRequest( InputStream in, OutputStream out ) { out = new BufferedOutputStream( out ); in = new BufferedInputStream( in ); try { String clientMessage = readMessage( in ); LabeledData clientRequest = new LabeledData(); clientRequest.fromString(clientMessage); String clientCommand = clientRequest.getData( COMMAND, "none" ); String returnMessage; if (clientCommand.equals( ENCODE ) ) returnMessage = encoded( clientRequest.getData( CODE_TYPE ), clientRequest.getData( DATA ) ); else if (clientCommand.equals( DECODE ) ) returnMessage = decoded( clientRequest.getData( CODE_TYPE ), clientRequest.getData( DATA ) ); else returnMessage = errorMessage( "Command not valid" ); out.write( returnMessage.getBytes() ); out.write( END_OF_MESSAGE ); out.flush(); } catch (IOException error) { System.err.println( "IOException in processing client request: " + error.getMessage() ); } }
TCPEncryptionServer Continued private String readMessage( InputStream in ) throws IOException { StringBuffer inputBuffer = new StringBuffer(); int inputChar = in.read(); while ( (inputChar != -1) && (inputChar != END_OF_MESSAGE)) { inputBuffer.append( (char) inputChar); inputChar = in.read(); } return inputBuffer.toString(); } private String encoded( String codeType, String text) { String encrypted = encrypter.encode( codeType, text ); return formatReturnMessage( DATA, encrypted ); } private String decoded( String codeType, String text) { String decrypted = encrypter.decode( codeType, text ); return formatReturnMessage( DATA, decrypted ); } private String formatReturnMessage( String key, String value) { LabeledData formater = new LabeledData(); formater.put( key, value ); return formater.toString(); } private String errorMessage( String error) { return formatReturnMessage( ERROR, error ); } }
EncryptionServerProxy
package whitney.jini.examples.serverProxy; import java.io.Serializable; import net.jini.core.lookup.ServiceID; import java.rmi.RemoteException; import java.net.Socket; import java.io.OutputStream; import java.io.InputStream; import java.io.IOException; import java.io.BufferedOutputStream; import java.io.BufferedInputStream; import sdsu.io.SimpleReader; import sdsu.util.LabeledData; import sdsu.util.ConversionException; public class EncryptionServerProxy implements EncryptionInterface, Serializable { private int serverPort; private String serverHost; static final String COMMAND = "command"; static final String ENCODE = "encode"; static final String DECODE = "decode"; static final String ERROR = "error"; static final String DATA = "data"; static final String CODE_TYPE = "codeType"; static final char END_OF_MESSAGE = '\u000C'; public EncryptionServerProxy( int port, String host ) { serverPort = port; serverHost = host; } public String[] encodeTypes() throws RemoteException { //Implemenation left to reader return null; } public String encode( String encodeType, String plainText ) throws RemoteException { return sendToServer( ENCODE, encodeType, plainText ); }
EncryptionServerProxy Continued public String decode( String encodeType, String encodedText) throws RemoteException { return sendToServer( DECODE, encodeType, encodedText ); } private String sendToServer( String command, String encodeType, String data ) throws RemoteException { LabeledData message = new LabeledData(); message.put( COMMAND, command ); message.put( DATA, data ); message.put( CODE_TYPE, encodeType.trim() ); String result = socketIO( message.toString()); LabeledData returnMessage = new LabeledData(); try { returnMessage.fromString( result ); } catch (ConversionException parseError ) { throw new RemoteException( "A error ocurred parsing server response: " + parseError.getMessage() ); } if ( returnMessage.containsKey( ERROR ) ) throw new RemoteException( "An error ocurred" + returnMessage.getData( ERROR) ); else return returnMessage.getData( DATA); }
EncryptionServerProxy Continued private String readMessage( InputStream in ) throws IOException { StringBuffer inputBuffer = new StringBuffer(); int inputChar = in.read(); while ( (inputChar != -1) && (inputChar != END_OF_MESSAGE)) { inputBuffer.append( (char)inputChar); inputChar = in.read(); } String inputMessage = inputBuffer.toString(); return inputMessage; } private String socketIO( String request ) throws RemoteException { try { Socket toServer = new Socket( serverHost, serverPort ); OutputStream out = new BufferedOutputStream( toServer.getOutputStream() ); out.write( request.getBytes() ); out.write( END_OF_MESSAGE ); out.flush(); InputStream in = toServer.getInputStream(); String response =readMessage( in ); out.close(); in.close(); return response; } catch (IOException socketProblem ) { throw new RemoteException( "Problem will socket to server" ); } }
EncryptionServerProxy Continued public int hashCode() { return serverHost.hashCode() + serverPort; // not a great hashCode, but points out the need to implement this method } public boolean equals(Object object) { if ( !(object instanceof EncryptionServerProxy) ) return false; EncryptionServerProxy otherObject = (EncryptionServerProxy) object; return ( (serverHost.equals( otherObject.serverHost) ) && (serverPort == otherObject.serverPort ) ); } }
RegisterTCPEncryption
package whitney.jini.examples.serverProxy; import com.sun.jini.lease.LeaseRenewalManager; import java.rmi.RMISecurityManager; import java.util.Date; import net.jini.core.discovery.LookupLocator; import net.jini.core.entry.Entry; import net.jini.core.lease.Lease; import net.jini.core.lookup.ServiceID; import net.jini.core.lookup.ServiceItem; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.lookup.ServiceRegistration; import net.jini.lookup.entry.Name; public class RegisterTCPEncryption { public static void main (String[] args) throws Exception { System.setSecurityManager (new RMISecurityManager ()); LookupLocator lookup = new LookupLocator ("jini://eli.sdsu.edu"); ServiceRegistrar registrar = lookup.getRegistrar (); Entry[] serverAttributes = new Entry[1]; serverAttributes[0] = new Name ("EncryptionService"); ServiceID serverID = null; int serverPort = 5432; String serverHost = "eli.sdsu.edu"; TCPEncryptionServer serverImpl = new TCPEncryptionServer( serverPort, (byte) 11 ); serverImpl.setDaemon( true); serverImpl.start(); EncryptionServerProxy theServerProxy = new EncryptionServerProxy(serverPort, serverHost); ServiceItem encryptServer = new ServiceItem( serverID, theServerProxy, serverAttributes); ServiceRegistration serverReg = registrar.register(encryptServer, 1000 * 60 ); System.out.println ( "Server registered" );
RegisterTCPEncryption Continued
Lease serverLease = serverReg.getLease(); LeaseRenewalManager manageLease = new LeaseRenewalManager( serverLease, Lease.FOREVER, null ); serverID = serverReg.getServiceID(); long now = (new Date()).getTime(); long leaseDuration = (serverLease.getExpiration() - now)/1000; System.out.println ( "Server id: " + serverID ); System.out.println ( "Server lease: " + serverLease ); System.out.println ( "Lease duration in seconds " + leaseDuration ); for (int k = 1; k <= 2; k++) { Thread.sleep( 1000 * 60 ); now = (new Date()).getTime(); leaseDuration = (serverLease.getExpiration() - now)/1000; System.out.println ( "Lease duration in seconds " + leaseDuration ); } System.out.println ( "Server going down: "); manageLease.cancel(serverLease); System.out.println ( "Done? "); serverImpl.interrupt(); System.out.println ( "Done: "); } }
Copyright ©, All rights reserved.
1999 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 05-Apr-99    Next