KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > carol > cmi > ClusterStubData


1 /*
2  * Copyright (C) 2002-2003, Simon Nieuviarts
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA
18  */

19 package org.objectweb.carol.cmi;
20
21 import java.io.IOException JavaDoc;
22 import java.io.ObjectInput JavaDoc;
23 import java.io.ObjectOutput JavaDoc;
24 import java.lang.reflect.Constructor JavaDoc;
25 import java.rmi.Remote JavaDoc;
26 import java.rmi.RemoteException JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30
31 /**
32  * Stubs to clustered objects use this class. They may contain several
33  * stubs to regular objects.
34  * @author Simon Nieuviarts
35  */

36 public class ClusterStubData {
37     /**
38      * Cluster configuration of this stub.
39      */

40     private ClusterConfig cfg;
41
42     /**
43      * A secure random seed, written at the ClusterStub creation.
44      */

45     private long randomSeed;
46
47     private boolean stubDebug = false;
48
49     private StubData firstSD;
50
51     // Updates on these variables have to be done with the lock on this
52
private HashMap JavaDoc idMap;
53     private HashSet JavaDoc stubs;
54     private volatile ClusterStub clusterStub;
55
56     private WeakList lbList = new WeakList();
57
58
59     /**
60      * for read(ObjectInput)
61      */

62     private ClusterStubData() {
63     }
64
65     /**
66      * Construct a new cluster stub data, containing a regular stub.
67      * @param serverId the cluster id of the server where the remote object is
68      * running.
69      * @param stubSer the regular stub, serialized.
70      * @param factor factor for round robin load lalancing.
71      */

72     public ClusterStubData(ClusterId serverId, byte[] stubSer, int factor)
73         throws RemoteException JavaDoc {
74         StubData sd = new StubData(serverId, stubSer, factor);
75         firstSD = sd;
76         idMap = new HashMap JavaDoc();
77         idMap.put(serverId, sd);
78         stubs = new HashSet JavaDoc();
79         stubs.add(sd);
80         randomSeed = SecureRandom.getLong();
81         stubDebug = Config.isStubDebug();
82     }
83
84     /**
85      * This must be called only for stubs without server id and load factor.
86      * Can be used only for the cluster registry.
87      * @param stub a stub to the registry.
88      */

89     ClusterStubData(ClusterRegistryInternal stub) throws RemoteException JavaDoc {
90         StubData sd = new StubData(stub);
91         firstSD = sd;
92         idMap = null;
93         stubs = new HashSet JavaDoc();
94         stubs.add(sd);
95         randomSeed = SecureRandom.getLong();
96         stubDebug = Config.isStubDebug();
97     }
98
99     private static Class JavaDoc[] cnstrParams = new Class JavaDoc[] { ClusterStubData.class };
100
101     public ClusterStub getClusterStub() throws RemoteException JavaDoc {
102         ClusterStub cs = clusterStub;
103         if (cs == null) {
104             Remote JavaDoc stub;
105             stub = firstSD.getStub();
106             Class JavaDoc clusterStubClass;
107             try {
108                 clusterStubClass =
109                     ClusterObject.getClusterStubClass(stub.getClass());
110             } catch (ClassNotFoundException JavaDoc e1) {
111                 throw new RemoteException JavaDoc("No valid cluster stub class for " + stub.getClass().getName());
112             }
113             Constructor JavaDoc cnstr;
114             try {
115                 cnstr = clusterStubClass.getConstructor(cnstrParams);
116                 cs = (ClusterStub) cnstr.newInstance(new Object JavaDoc[] { this });
117             } catch (Exception JavaDoc e) {
118                 throw new RemoteException JavaDoc("Can not instanciate cluster stub" + e.toString());
119             }
120             clusterStub = cs;
121         }
122         return cs;
123     }
124
125 /*
126     public boolean isValidRemote(Remote r) {
127         try {
128             return clusterStubClass.getName().equals(
129                 ClusterObject.getClusterStubClass(r.getClass()).getName());
130         } catch (ClassNotFoundException e) {
131             return false;
132         }
133     }
134 */

135
136     /**
137      * Add a regular stub in this cluster stub.
138      * @param serverId the cluster id of the server where the remote object
139      * is running.
140      * @param stub the regular stub.
141      * @return false if the class of the stub is not the same the other objects
142      * in the stub, or if factor is < 1.
143      */

144     public boolean setStub(ClusterId serverId, byte[] stubSer, int factor) {
145         if (idMap == null) {
146             return false;
147         }
148 /*
149         if (!isValidRemote(stub)) {
150             return false;
151         }
152 */

153                 StubData sd;
154         try {
155             sd = new StubData(serverId, stubSer, factor);
156         } catch (RemoteException JavaDoc e) {
157             return false;
158         }
159         synchronized (this) {
160             idMap.put(serverId, sd);
161             stubs.add(sd);
162         }
163         return true;
164     }
165
166     /**
167      * Add a regular stub in this cluster stub.
168      * Can be used only for the cluster registry.
169      * @param stub a stub to a registry.
170      * @return false if the class of the stub is not the same the other objects
171      * in the stub.
172      */

173     public boolean setStub(ClusterRegistryInternal stub) {
174         if (idMap != null) {
175             return false;
176         }
177         StubData sd = new StubData(stub);
178         synchronized (this) {
179             stubs.add(sd);
180         }
181         return true;
182     }
183
184     /**
185      * Serialize this object. Used by the encapsulating ClusterStub.
186      * @param out the output stream
187      * @throws IOException
188      */

189     public void write(ObjectOutput JavaDoc out) throws IOException JavaDoc {
190         out.writeObject(cfg);
191         synchronized (this) {
192             Iterator JavaDoc it = stubs.iterator();
193             int l = stubs.size();
194             if (idMap == null) {
195                 out.writeInt(-l);
196                 for (int i = 0; i < l; i++) {
197                     StubData sd = (StubData) it.next();
198                     out.writeInt(sd.getFactor());
199                     Object JavaDoc o = sd.getStubOrException();
200                     if (o instanceof Remote JavaDoc) {
201                         out.writeObject(o);
202                     } else {
203                         out.writeObject(sd.getSerializedStub());
204                     }
205                 }
206             } else {
207                 out.writeInt(l);
208                 for (int i = 0; i < l; i++) {
209                     StubData sd = (StubData) it.next();
210                     sd.getId().write(out);
211                     out.writeInt(sd.getFactor());
212                     Object JavaDoc o = sd.getStubOrException();
213                     if (o instanceof Remote JavaDoc) {
214                         out.writeObject(o);
215                     } else {
216                         out.writeObject(sd.getSerializedStub());
217                     }
218                 }
219             }
220         }
221         out.writeLong(randomSeed);
222         out.writeBoolean(stubDebug);
223     }
224
225     /**
226      * Deserialize a ClusterStubData.
227      * @param in input stream
228      * @return the object
229      * @throws IOException
230      */

231     public static ClusterStubData read(ObjectInput JavaDoc in, ClusterStub cs)
232         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
233         ClusterStubData csd = new ClusterStubData();
234         StubData first = null;
235         try {
236             csd.cfg = (ClusterConfig) in.readObject();
237             int l = in.readInt();
238             if (l == 0) {
239                 throw new IOException JavaDoc("invalid serialized stub : 0 stubs");
240             }
241             HashMap JavaDoc idm = null;
242             HashSet JavaDoc stubs = new HashSet JavaDoc();
243             if (l < 0) {
244                 l = -l;
245                 for (int i = 0; i < l; i++) {
246                     int f = in.readInt();
247                     Object JavaDoc obj = in.readObject();
248                     System.err.println(obj.getClass().getName());
249                     StubData sd;
250                     if (obj instanceof Remote JavaDoc) {
251                         sd = new StubData(null, (Remote JavaDoc) obj, f);
252                     } else {
253                         sd = new StubData(null, (byte[]) obj, f);
254                     }
255                     stubs.add(sd);
256                     if (first == null) {
257                         first = sd;
258                     }
259                 }
260             } else {
261                 idm = new HashMap JavaDoc(l);
262                 for (int i = 0; i < l; i++) {
263                     ClusterId id = ClusterId.read(in);
264                     int f = in.readInt();
265
266                     Object JavaDoc obj = in.readObject();
267                     StubData sd;
268                     if (obj instanceof Remote JavaDoc) {
269                         sd = new StubData(id, (Remote JavaDoc) obj, f);
270                     } else {
271                         sd = new StubData(id, (byte[]) obj, f);
272                     }
273                     stubs.add(sd);
274                     idm.put(id, sd);
275                     if (first == null) {
276                         first = sd;
277                     }
278                 }
279             }
280             csd.idMap = idm;
281             csd.stubs = stubs;
282             SecureRandom.setSeed(
283                 csd.randomSeed = in.readLong() ^ System.currentTimeMillis());
284             csd.stubDebug = in.readBoolean();
285         } catch (ClassCastException JavaDoc ce) {
286             ce.printStackTrace();
287             throw new IOException JavaDoc("invalid serialized stub " + ce.toString());
288         }
289         csd.clusterStub = cs;
290         csd.firstSD = first;
291         return csd;
292     }
293
294     /*
295         public void printStub() {
296             System.out.println("Stub inside : ");
297             java.util.Iterator i = stubMap.keySet().iterator();
298             while (i.hasNext()) {
299                 System.out.println(i.next());
300             }
301         }
302     */

303     /**
304      * This function fails if and only if the stub to remove is the last one.
305      */

306     public boolean removeStub(ClusterId serverId) {
307         StubData sd;
308         synchronized (this) {
309             sd = (StubData) idMap.remove(serverId);
310             if (sd == null) {
311                 return true;
312             }
313             if (idMap.size() == 0) {
314                 idMap.put(serverId, sd);
315                 return false;
316             }
317             stubs.remove(sd);
318             removeFromLB(sd);
319         }
320         return true;
321     }
322
323     /**
324      * This function fails if and only if the stub to remove is the last one.
325      */

326     public boolean removeStubData(StubData sd) {
327         synchronized (this) {
328             if (!stubs.remove(sd)) {
329                 return true;
330             }
331             if (stubs.size() == 0) {
332                 stubs.add(sd);
333                 return false;
334             }
335             idMap.remove(sd.getId());
336             removeFromLB(sd);
337         }
338         return true;
339     }
340
341     private void removeFromLB(StubData sd) {
342         Iterator JavaDoc it = lbList.iterator();
343         while (it.hasNext()) {
344             StubLB lb = (StubLB) it.next();
345             lb.removeCallback(sd);
346         }
347     }
348
349     public void setClusterConfig(ClusterConfig cfg) {
350         this.cfg = cfg;
351     }
352
353     /**
354      * You can assume it returns a non null structure if it is not
355      * a stub to a cluster registry. cfg should have been initialized by
356      * the constructor
357      */

358     public ClusterConfig getClusterConfig() {
359         return cfg;
360     }
361
362     public StubLB getRoundRobin() {
363         StubLB lb;
364         // Synchronize to avoid Exceptions for concurrent modifications
365
synchronized (this) {
366             lb = new RoundRobin(this, stubs);
367         }
368         lbList.put(lb);
369         return lb;
370     }
371
372     public StubLB getRandom() {
373         StubLB lb;
374         // Synchronize to avoid Exceptions for concurrent modifications
375
synchronized (this) {
376             lb = new Random(this, stubs);
377         }
378         lbList.put(lb);
379         return lb;
380     }
381
382     public StubData getLocal() throws NoLocalStubException {
383         synchronized (this) {
384             Iterator JavaDoc it = stubs.iterator();
385             while (it.hasNext()) {
386                 StubData sd = (StubData)it.next();
387                 System.out.println(sd.getStubOrException());
388             }
389         }
390         throw new NoLocalStubException();
391     }
392
393     public boolean isStubDebug() {
394         return stubDebug;
395     }
396
397     public void debug(String JavaDoc mesg) {
398         System.out.println("ClusterStub: " + mesg);
399     }
400
401     public String JavaDoc toContentsString() {
402         synchronized (this) {
403             Iterator JavaDoc it = stubs.iterator();
404             if (!it.hasNext()) {
405                 return "[]";
406             }
407             String JavaDoc str = "[ " + it.next().toString();
408             while (it.hasNext()) {
409                 str = str + ", " + it.next().toString();
410             }
411             str = str + " ]";
412             return str;
413         }
414     }
415
416     public String JavaDoc toString() {
417         return this.getClass().getName() + toContentsString();
418     }
419 }
420
Popular Tags