KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > regis > remote > RegistryExporter


1 package org.sapia.regis.remote;
2
3 import java.io.IOException JavaDoc;
4 import java.util.Collections JavaDoc;
5 import java.util.HashMap JavaDoc;
6 import java.util.Map JavaDoc;
7 import java.util.Properties JavaDoc;
8
9 import javax.naming.InitialContext JavaDoc;
10
11 import org.sapia.regis.Registry;
12 import org.sapia.ubik.mcast.AsyncEventListener;
13 import org.sapia.ubik.mcast.EventChannel;
14 import org.sapia.ubik.mcast.RemoteEvent;
15 import org.sapia.ubik.rmi.Consts;
16 import org.sapia.ubik.rmi.naming.remote.RemoteInitialContextFactory;
17 import org.sapia.ubik.rmi.server.Hub;
18 import org.sapia.ubik.rmi.server.invocation.ServerPostInvokeEvent;
19 import org.sapia.ubik.rmi.server.invocation.ServerPreInvokeEvent;
20
21 /**
22  * An instance of this class exports a <code>Registry</code> as
23  * a remote object.
24  * <p>
25  * The <code>Registry</code> that his held by an instance of this
26  * class will internally be made available through the network upon
27  * one of the <code>bind()</code> methods being called.
28  * <p>
29  * To lookup a <code>Registry</code> that has been bound by an
30  * instance of this class, applications can use a <code>RegistryImporter</code>,
31  * or a <code>RemoteRegistryFactory</code>.
32  *
33  * @see #bind(int)
34  * @see #bind(String, Properties)
35  * @see org.sapia.regis.remote.client.RegistryImporter
36  * @see org.sapia.regis.remote.client.RemoteRegistryFactory
37  */

38 public class RegistryExporter implements RemoteConsts, AsyncEventListener{
39
40   public static final String JavaDoc PUBLISH = "org.sapia.regis.remote.pub";
41   public static final String JavaDoc DISCO = "org.sapia.regis.remote.disco";
42   
43   private RemoteRegistry _reg;
44   private boolean _peerToPeer = false;
45   private EventChannel _channel;
46   private Object JavaDoc _stub;
47   private Map JavaDoc _peers = Collections.synchronizedMap(new HashMap JavaDoc());
48   private String JavaDoc _domain = Consts.DEFAULT_DOMAIN;
49   
50   public RegistryExporter(Registry reg, Properties JavaDoc bootstrapProps){
51     _reg = new RemoteRegistry(new Authenticator(USERNAME, PASSWORD), reg, bootstrapProps);
52   }
53   
54   public RegistryExporter(String JavaDoc username, String JavaDoc password, Registry reg, Properties JavaDoc bootstrapProps){
55     _reg = new RemoteRegistry(new Authenticator(username, password), reg, bootstrapProps);
56   }
57   
58   /**
59    * @param peerToPeer indicates if this instance should behave as peer in a network of registries
60    * - by default, this instance is not in peer-to-peer mode.
61    */

62   public void setPeerToPeer(boolean peerToPeer){
63     _peerToPeer = peerToPeer;
64   }
65   
66   /**
67    * @param domain the name of the domain to which this instance belongs.
68    */

69   public void setDomain(String JavaDoc domain){
70     _domain = domain;
71   }
72   
73   /**
74    * Closes this instance (which releases all system resources it holds).
75    */

76   public void close(){
77     if(_channel != null){
78       _channel.close();
79     }
80     _reg.close();
81   }
82   
83   /**
84    * This method bind the <code>Registry</code> held by this
85    * instance on the network, on the given port. The registry thus
86    * becomes available as a remote object.
87    * <p>
88    * Clients can connect to the registry through the Ubik <code>Hub</code>:
89    * <pre>
90    * // connects on the given host, port
91    * Registry reg = (Registry)Hub.connect("192.168.0.101", 40000);
92    * </pre>
93    * <p>
94    * Note that Ubik runtime attempts to bind servers on addresses that match the
95    * value of the <code>ubik.rmi.address-pattern</code> system property. If that
96    * property is not defined, then the address used will be the first that DOES NOT
97    * correspond to "localhost" or 127.0.0.1. If no such address exists, then "localhost"
98    * is internally used.
99    * <p>
100    * If "localhost" must be used (for testing purposes for example), then the
101    * <code>ubik.rmi.address-pattern</code> system property should be set, with
102    * <code>localhost</code> as a value.
103    *
104    * @param port a port
105    * @throws Exception if the registry could not be exported
106    */

107   public void bind(int port) throws Exception JavaDoc{
108     SessionInterceptor interceptor = new SessionInterceptor(_reg);
109     System.out.println("Binding server to port: " + port);
110     Hub.serverRuntime.addInterceptor(ServerPreInvokeEvent.class, interceptor);
111     Hub.serverRuntime.addInterceptor(ServerPostInvokeEvent.class, interceptor);
112     _stub = Hub.exportObject(_reg, port);
113     publish(System.getProperties());
114   }
115   
116   /**
117    * This method binds the <code>Registry</code> held by this
118    * instance to the JNDI service that corresponds to the given properties, under
119    * the given JNDI name.
120    * <p>
121    * The properties passed in correspond to the ones expected by Ubik's JNDI provider
122    * (see the <a HREF="http://www.sapia-oss.org/projects/ubik/naming.html#robust">tutorial</a>)
123    * <ul>
124    * <li><b>java.naming.provider.url</b>: this is a property specified by the JNDI spec. It is interpreted
125    * by Ubik as corresdoning to the remote JNDI server to connect to (example
126    * <code>ubik://localhost:1099</code>).
127    * <li><b>ubik.jndi.domain</b>: the logical domain name of the a remote JNDI server to
128    * connect to, if one could not be found on the specified URL.
129    * <li><b>ubik.rmi.naming.mcast.address</b>: the multicast address to use when trying to perform
130    * client-side discovery of remote a JNDI server corresponding to the specified domain - see
131    * previous property (the address defaults to 224.0.0.1).
132    * <li><b>ubik.rmi.naming.mcast.port</b>: the multicast port to use when trying to perform
133    * client-side discovery of remote a JNDI server corresponding to the specified domain - see
134    * previous property (the port defaults to 5454).
135    * </ul>
136    * <p>
137    * Client applications can lookup a registry exported by this instance using a <code>RegistryImporter</code>,
138    * or a <code>RemoteRegistryFactory</code>.
139    * <p>
140    * For more info concerning the properties defined above, see the javadoc for the
141    * <a HREF="http://www.sapia-oss.org/projects/ubik/api/org/sapia/ubik/rmi/Consts.html">
142    * Const</a> class.
143    *
144    * @param jndiName the JNDI name under which the registry should be
145    * bound in the Ubik JNDI service.
146    * @param props must hold Ubik JNDI properties
147    * @throws Exception if the registry could not be bound to the JNDI service.
148    *
149    * @see <code>RegistryImporter</code>
150    */

151   public void bind(String JavaDoc jndiName, Properties JavaDoc props) throws Exception JavaDoc{
152     SessionInterceptor interceptor = new SessionInterceptor(_reg);
153     Hub.serverRuntime.addInterceptor(ServerPreInvokeEvent.class, interceptor);
154     Hub.serverRuntime.addInterceptor(ServerPostInvokeEvent.class, interceptor);
155     props.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
156     InitialContext JavaDoc ctx = new InitialContext JavaDoc(props);
157     _stub = Hub.exportObject(_reg);
158     ctx.bind(jndiName, _reg);
159     ctx.close();
160     publish(props);
161   }
162   
163   private void publish(Properties JavaDoc props) throws IOException JavaDoc{
164     if(_peerToPeer){
165       String JavaDoc mcastHost = props.getProperty(Consts.MCAST_ADDR_KEY, Consts.DEFAULT_MCAST_ADDR);
166       int mcastPort = Integer.parseInt(props.getProperty(Consts.MCAST_PORT_KEY, ""+Consts.DEFAULT_MCAST_PORT));
167       _channel = new EventChannel(_domain, mcastHost, mcastPort);
168       _channel.registerAsyncListener(PUBLISH, this);
169       _channel.registerAsyncListener(DISCO, this);
170       _channel.start();
171       _channel.dispatch(PUBLISH, _stub);
172       _reg.setPeers(_peers);
173     }
174   }
175   
176   public void onAsyncEvent(RemoteEvent evt) {
177     if(evt.getType().equals(PUBLISH)){
178       try{
179         ServerDebug.debug(this, "New peer was published");
180         synchronized(_peers){
181           if(!_peers.containsKey(evt.getNode())){
182             _peers.put(evt.getNode(), evt.getData());
183           }
184           _channel.dispatch(DISCO, _stub);
185         }
186       }catch(IOException JavaDoc e){
187         e.printStackTrace();
188       }
189     }
190     else if(evt.getType().equals(DISCO)){
191       try{
192         ServerDebug.debug(this, "Discovered peer");
193         synchronized(_peers){
194           if(!_peers.containsKey(evt.getNode())){
195             _peers.put(evt.getNode(), evt.getData());
196           }
197         }
198       }catch(IOException JavaDoc e){
199         e.printStackTrace();
200       }
201     }
202   }
203 }
204
Popular Tags