KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > module > builders > MMServers


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10
11 package org.mmbase.module.builders;
12
13 import java.util.*;
14
15 import org.mmbase.module.core.*;
16 import org.mmbase.util.functions.*;
17 import org.mmbase.util.logging.*;
18 import org.mmbase.storage.search.implementation.*;
19 import org.mmbase.storage.search.*;
20
21 /**
22  * @javadoc
23  * mmservers stands for MMBase servers. It is possible to run multiple mmbase servers on one database instance.
24  * Every mmserver node represent a real MMBase server(think of it as a machine where one instance of MMBase is running).
25  * On startup MMBase looks in the mmservers table and looks if he is listed in the list of mmservers,
26  * if not MMBase create a new node containing imfornation about itselve(name/host/os/jdk). the mmservers builder has extra behaviour,
27  * it can communicate with other servers(using multicast). The basic funtionality it provides however is sending information
28  * about changes of node to other mmservers (Listen !! I just have changed node 123). This mechanisme makes it possible to keep
29  * nodes caches in sync but also makes it possible to split tasks between machines. You could for example have a server that encodes video.
30  * when a change to a certain node is made one of the servers (if wel configured) can start encoding the videos.
31  * @author vpro
32  * @version $Id: MMServers.java,v 1.44.2.1 2006/12/05 19:40:04 michiel Exp $
33  */

34 public class MMServers extends MMObjectBuilder implements MMBaseObserver, Runnable JavaDoc, org.mmbase.datatypes.resources.StateConstants {
35
36     private static final Logger log = Logging.getLoggerInstance(MMServers.class);
37     private int serviceTimeout = 60 * 15; // 15 minutes
38
private long intervalTime = 60 * 1000; // 1 minute
39

40     private boolean checkedSystem = false;
41     private String JavaDoc javastr;
42     private String JavaDoc osstr;
43     private Vector possibleServices = new Vector();
44
45     /**
46      * Function uptime
47      * @since MMBase-1.8
48      */

49     protected Function getUpTime = new AbstractFunction("uptime", Parameter.EMPTY, ReturnType.LONG) {
50             {
51                 setDescription("The function 'uptime' returns the uptime of the current server.");
52             }
53             public Object JavaDoc getFunctionValue(Parameters parameters) {
54                 int now = (int) (System.currentTimeMillis() / 1000);
55                 return new Long JavaDoc(now - MMBase.startTime);
56             }
57         };
58     {
59         addFunction(getUpTime);
60     }
61
62     /**
63      * @javadoc
64      */

65     public MMServers() {
66         javastr = System.getProperty("java.version") + "/" + System.getProperty("java.vm.name");
67         osstr = System.getProperty("os.name") + "/" + System.getProperty("os.version");
68     }
69
70     public boolean init() {
71         if (oType != -1)
72             return true; // inited already
73
if (!super.init())
74             return false;
75         String JavaDoc tmp = getInitParameter("ProbeInterval");
76         if (tmp != null) {
77             intervalTime = (long)Integer.parseInt(tmp) * 1000;
78             log.service("ProbeInterval was configured to be " + intervalTime / 1000 + " seconds");
79         } else {
80             log.service("ProbeInterval defaults to " + intervalTime / 1000 + " seconds");
81         }
82          tmp = getInitParameter("ServiceTimeout");
83         if (tmp != null) {
84             serviceTimeout = (int)Integer.parseInt(tmp);
85             log.service("ServiceTimeout was configured to be " + serviceTimeout + " seconds");
86         } else {
87             log.service("ServiceTimeout defaults to " + serviceTimeout + " seconds");
88         }
89         start();
90         return true;
91     }
92
93     /**
94      * Starts the thread for the task scheduler
95      * @since MMBase-1.7
96      */

97     protected void start() {
98         MMBaseContext.startThread(this,"MMServers");
99     }
100
101     /**
102      * @javadoc
103      */

104     public Object JavaDoc getValue(MMObjectNode node, String JavaDoc field) {
105         if (field.equals("showstate")) {
106             return getGUIIndicator("state", node);
107         } else if (field.equals("showatime")) {
108             return getGUIIndicator("atime", node);
109         } else if (field.equals("uptime")) {
110             // The 'node' object is not used, so this info makes only sense for _this_ server.
111
int now = (int) (System.currentTimeMillis() / 1000);
112             int uptime = now - MMBase.startTime;
113             return getUptimeString(uptime);
114         }
115         return super.getValue(node, field);
116     }
117
118     /**
119      * @javadoc
120      */

121     private String JavaDoc getUptimeString(int uptime) {
122         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
123         if (uptime >= (24 * 3600)) {
124             int d = uptime / (24 * 3600);
125             result.append(d).append(" d ");
126             uptime -= d * 24 * 3600;
127         }
128         if (uptime >= 3600) {
129             int h = uptime / 3600;
130             result.append(h).append(" h ");
131             uptime -= h * 3600;
132         }
133         if (uptime >= 60) {
134             int m = uptime / (60);
135             result.append(m).append(" m ");
136             uptime -= m * 60;
137         }
138         result.append(uptime).append(" s");
139         return result.toString();
140     }
141
142     /**
143      * run, checkup probe runs every intervaltime to
144      * set the state of the server (used in clusters)
145      * @since MMBase-1.7
146      */

147     public void run() {
148         while (!mmb.isShutdown()) {
149             long thisTime = intervalTime;
150             if (mmb != null && mmb.getState()) {
151                 doCheckUp();
152             } else {
153                 // shorter wait, the server is starting
154
thisTime = 2 * 1000; // wait 2 second
155
}
156
157             // wait the defined time
158
try {
159                 Thread.sleep(thisTime);
160             } catch (InterruptedException JavaDoc e) {
161                 log.debug(Thread.currentThread().getName() +" was interrupted.");
162                 continue;
163             }
164         }
165     }
166
167     /**
168      * @javadoc
169      */

170     private void doCheckUp() {
171         try {
172             boolean imoke = false;
173             String JavaDoc machineName = mmb.getMachineName();
174             String JavaDoc host = mmb.getHost();
175             log.debug("doCheckUp(): machine=" + machineName);
176             for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
177                 MMObjectNode node = (MMObjectNode) iter.next();
178                 String JavaDoc name = node.getStringValue("name");
179                 String JavaDoc h = node.getStringValue("host");
180                 log.debug("Checking " + name + "@" + h);
181                 if (name.equals(machineName) && h.equals(host)) {
182                     imoke = checkMySelf(node);
183                 } else {
184                     checkOther(node);
185                 }
186             }
187             if (!imoke) {
188                 createMySelf(machineName);
189             }
190         } catch (Exception JavaDoc e) {
191             log.error("Something went wrong in MMServers Checkup Thread " + e.getMessage(), e);
192         }
193     }
194
195     /**
196      * @javadoc
197      */

198     private boolean checkMySelf(MMObjectNode node) {
199         boolean state = true;
200         log.debug("checkMySelf() updating timestamp");
201         node.setValue("state", ACTIVE);
202         node.setValue("atime", (int) (System.currentTimeMillis() / 1000));
203         if (!checkedSystem) {
204             node.setValue("os", osstr);
205             node.setValue("host", mmb.getHost());
206             node.setValue("jdk", javastr);
207             checkedSystem = true;
208         }
209         node.commit();
210         log.debug("checkMySelf() updating timestamp done");
211         return state;
212     }
213
214     /**
215      * @javadoc
216      */

217     private void checkOther(MMObjectNode node) {
218         int now = (int) (System.currentTimeMillis() / 1000);
219         int then = node.getIntValue("atime");
220         if (log.isDebugEnabled()) {
221             log.debug("" + now + ": Checking " + node.getValue("name") + " (updated at " + then + ", " + (now - then) + " s ago, interval: " + serviceTimeout + " s )" );
222         }
223         if ((now - then) > (serviceTimeout)) {
224             if (node.getIntValue("state") != INACTIVE) {
225                 log.debug("checkOther() updating state for " + node.getStringValue("host"));
226                 node.setValue("state", INACTIVE);
227                 node.commit();
228
229                 // now also signal all its services are down !
230
setServicesDown(node);
231             }
232         }
233     }
234
235     /**
236      * @javadoc
237      */

238     private void createMySelf(String JavaDoc machineName) {
239         MMObjectNode node = getNewNode("system");
240         node.setValue("name", machineName);
241         node.setValue("state", ACTIVE);
242         node.setValue("atime", (int) (System.currentTimeMillis() / 1000));
243         node.setValue("os", osstr);
244         node.setValue("host", mmb.getHost());
245         node.setValue("jdk", javastr);
246         insert("system", node);
247     }
248
249     /**
250      * @javadoc
251      */

252     private void setServicesDown(MMObjectNode node) {
253         Enumeration f = possibleServices.elements();
254         log.debug("setServicesDown() for " + node);
255         while (f.hasMoreElements()) {
256             String JavaDoc type = (String JavaDoc)f.nextElement();
257             Enumeration e = mmb.getInsRel().getRelated(node.getIntValue("number"), type);
258             while (e.hasMoreElements()) {
259                 MMObjectNode node2 = (MMObjectNode)e.nextElement();
260                 MMObjectBuilder parent = node2.getBuilder();
261                 log.info("setServicesDown(): downnode(" + node2 + ") REMOVING node");
262                 parent.removeRelations(node2);
263                 parent.removeNode(node2);
264
265                 //node2.setValue("state","down");
266
//node2.commit();
267
}
268         }
269         if (log.isDebugEnabled()) {
270             log.debug("setServicesDown() for " + node + " done");
271         }
272     }
273
274     /**
275      * @javadoc
276      */

277     public void setCheckService(String JavaDoc name) {
278         if (!possibleServices.contains(name)) {
279             possibleServices.addElement(name);
280         }
281     }
282
283     /**
284      * @javadoc
285      */

286     public String JavaDoc getMMServerProperty(String JavaDoc mmserver, String JavaDoc key) {
287         String JavaDoc value = getInitParameter(mmserver + ":" + key);
288         return value;
289     }
290
291     /**
292      * @javadoc
293      */

294     public MMObjectNode getMMServerNode(String JavaDoc name) {
295         return getMMServerNode(name, null);
296     }
297
298     /**
299      * @since MMBase-1.8.3
300      */

301     public MMObjectNode getMMServerNode(String JavaDoc name, String JavaDoc host) {
302         NodeSearchQuery query = new NodeSearchQuery(this);
303         Constraint constraint = new BasicFieldValueConstraint(query.getField(getField("name")), name);
304         if (host != null) {
305             BasicCompositeConstraint comp = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
306             comp.addChild(constraint);
307             BasicFieldValueConstraint constraint2 = new BasicFieldValueConstraint(query.getField(getField("host")), host);
308             comp.addChild(constraint2);
309             constraint = comp;
310         }
311         query.setConstraint(constraint);
312         try {
313             List nodeList = getNodes(query);
314             if (nodeList.size() > 0) {
315                 return (MMObjectNode) nodeList.get(0);
316             } else {
317                 log.info("Can't find any mmserver node with name=" + name);
318                 return null;
319             }
320         } catch (SearchQueryException sqe) {
321             log.warn(sqe);
322             return null;
323         }
324     }
325
326     /**
327      * @return Returns the intervalTime.
328      */

329     public long getIntervalTime() {
330         return intervalTime;
331     }
332
333     /**
334      * MMServer object are field by field equals.
335      */

336
337     public boolean equals(MMObjectNode o1, MMObjectNode o2) {
338         return o1 == null ? o2 == null : o2 != null && (o1.getNumber() == o2.getNumber() && o1.getValue("name").equals(o2.getValue("name")) && o1.getValue("host").equals(o2.getValue("host")));
339     }
340
341     public String JavaDoc toString(MMObjectNode n) {
342         return "" + n.getValue("name") + "@" + n.getValue("host");
343     }
344
345
346
347     protected NodeSearchQuery query = null;
348     /**
349      * @return List of MMObjectNodes representing active servers, which are not this server.
350      */

351     public List getActiveServers() {
352         String JavaDoc machineName = mmb.getMachineName();
353         String JavaDoc host = mmb.getHost();
354         if (log.isDebugEnabled()) {
355             log.debug("machine=" + machineName + " host=" + host);
356         }
357         if (query == null) {
358             query = new NodeSearchQuery(this);
359             BasicFieldValueConstraint constraint1a = new BasicFieldValueConstraint(query.getField(getField("name")), machineName);
360             BasicFieldValueConstraint constraint1b = new BasicFieldValueConstraint(query.getField(getField("host")), host);
361             BasicCompositeConstraint constraint1 = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
362             constraint1.addChild(constraint1a);
363             constraint1.addChild(constraint1b);
364             constraint1.setInverse(true);
365             BasicFieldValueConstraint constraint2 = new BasicFieldValueConstraint(query.getField(getField("state")), new Integer JavaDoc(ACTIVE));
366             BasicCompositeConstraint constraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
367             constraint.addChild(constraint1);
368             constraint.addChild(constraint2);
369             query.setConstraint(constraint);
370             StepField field = query.getField(getField(FIELD_NUMBER));
371             BasicSortOrder so = query.addSortOrder(field);
372             so.setDirection(SortOrder.ORDER_DESCENDING);
373         }
374
375         try {
376             return storageConnector.getNodes(query, false);
377         } catch (org.mmbase.storage.search.SearchQueryException sqe) {
378             log.error(sqe);
379             return new ArrayList();
380         }
381     }
382 }
383
Popular Tags