001: /*
002: License $Id: JoXMLBalancerBuilder.java,v 1.4 2003/09/13 04:59:58 hendriks73 Exp $
003:
004: Copyright (c) 2001-2005 tagtraum industries.
005:
006: LGPL
007: ====
008:
009: jo! is free software; you can redistribute it and/or
010: modify it under the terms of the GNU Lesser General Public
011: License as published by the Free Software Foundation; either
012: version 2.1 of the License, or (at your option) any later version.
013:
014: jo! is distributed in the hope that it will be useful,
015: but WITHOUT ANY WARRANTY; without even the implied warranty of
016: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: Lesser General Public License for more details.
018:
019: You should have received a copy of the GNU Lesser General Public
020: License along with this library; if not, write to the Free Software
021: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022:
023: For LGPL see <http://www.fsf.org/copyleft/lesser.txt>
024:
025:
026: Sun license
027: ===========
028:
029: This release contains software by Sun Microsystems. Therefore
030: the following conditions have to be met, too. They apply to the
031: files
032:
033: - lib/mail.jar
034: - lib/activation.jar
035: - lib/jsse.jar
036: - lib/jcert.jar
037: - lib/jaxp.jar
038: - lib/crimson.jar
039: - lib/servlet.jar
040: - lib/jnet.jar
041: - lib/jaas.jar
042: - lib/jaasmod.jar
043:
044: contained in this release.
045:
046: a. Licensee may not modify the Java Platform
047: Interface (JPI, identified as classes contained within the javax
048: package or any subpackages of the javax package), by creating additional
049: classes within the JPI or otherwise causing the addition to or modification
050: of the classes in the JPI. In the event that Licensee creates any
051: Java-related API and distribute such API to others for applet or
052: application development, you must promptly publish broadly, an accurate
053: specification for such API for free use by all developers of Java-based
054: software.
055:
056: b. Software is confidential copyrighted information of Sun and
057: title to all copies is retained by Sun and/or its licensors. Licensee
058: shall not modify, decompile, disassemble, decrypt, extract, or otherwise
059: reverse engineer Software. Software may not be leased, assigned, or
060: sublicensed, in whole or in part. Software is not designed or intended
061: for use in on-line control of aircraft, air traffic, aircraft navigation
062: or aircraft communications; or in the design, construction, operation or
063: maintenance of any nuclear facility. Licensee warrants that it will not
064: use or redistribute the Software for such purposes.
065:
066: c. Software is provided "AS IS," without a warranty
067: of any kind. ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES,
068: INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
069: PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
070:
071: d. This License is effective until terminated. Licensee may
072: terminate this License at any time by destroying all copies of Software.
073: This License will terminate immediately without notice from Sun if Licensee
074: fails to comply with any provision of this License. Upon such termination,
075: Licensee must destroy all copies of Software.
076:
077: e. Software, including technical data, is subject to U.S.
078: export control laws, including the U.S. Export Administration Act and its
079: associated regulations, and may be subject to export or import regulations
080: in other countries. Licensee agrees to comply strictly with all such
081: regulations and acknowledges that it has the responsibility to obtain
082: licenses to export, re-export, or import Software. Software may not be
083: downloaded, or otherwise exported or re-exported (i) into, or to a national
084: or resident of, Cuba, Iraq, Iran, North Korea, Libya, Sudan, Syria or any
085: country to which the U.S. has embargoed goods; or (ii) to anyone on the
086: U.S. Treasury Department's list of Specially Designated Nations or the U.S.
087: Commerce Department's Table of Denial Orders.
088:
089:
090: Feedback
091: ========
092:
093: We encourage your feedback and suggestions and want to use your feedback to
094: improve the Software. Send all such feedback to:
095: <feedback@tagtraum.com>
096:
097: For more information on tagtraum industries and jo!
098: please see <http://www.tagtraum.com/>.
099:
100:
101: */
102: package com.tagtraum.jobalancer.builder;
103:
104: import com.tagtraum.framework.log.C_Log;
105: import com.tagtraum.framework.log.Log;
106: import com.tagtraum.framework.log.LogFileWriter;
107: import com.tagtraum.framework.log.LogWriter;
108: import com.tagtraum.framework.server.I_Service;
109: import com.tagtraum.framework.server.I_TCPListener;
110: import com.tagtraum.framework.server.TCPListener;
111: import com.tagtraum.framework.util.*;
112: import com.tagtraum.jobalancer.JoBalancer;
113: import org.w3c.dom.Document;
114: import org.w3c.dom.Node;
115:
116: import javax.xml.parsers.DocumentBuilder;
117: import javax.xml.parsers.DocumentBuilderFactory;
118: import java.io.IOException;
119: import java.net.InetAddress;
120: import java.net.MalformedURLException;
121: import java.net.URL;
122: import java.util.Enumeration;
123:
124: /**
125: *
126: * @author Hendrik Schreiber
127: * @version 1.1beta1 $Id: JoXMLBalancerBuilder.java,v 1.4 2003/09/13 04:59:58 hendriks73 Exp $
128: */
129: public class JoXMLBalancerBuilder extends AbstractBuilder {
130:
131: /**
132: * Source-Version
133: */
134: public static String vcid = "$Id: JoXMLBalancerBuilder.java,v 1.4 2003/09/13 04:59:58 hendriks73 Exp $";
135:
136: /**
137: * Returns false for now.
138: */
139: public boolean needsRebuild() {
140: return false;
141: }
142:
143: /**
144: * Not implemented.
145: */
146: public void rebuild(Object obj) throws BuildException {
147: throw new BuildException("Not implemented.");
148: }
149:
150: /**
151: *
152: */
153: public Object build() throws BuildException {
154: JoBalancer balancer = null;
155: try {
156: balancer = new JoBalancer();
157: // read balancer.xml and build DOM
158: DocumentBuilderFactory theDocumentBuilderFactory = DocumentBuilderFactory
159: .newInstance();
160: // setValidating to false
161: theDocumentBuilderFactory.setValidating(false);
162: // get DocumentBuilder
163: DocumentBuilder theDocumentBuilder = theDocumentBuilderFactory
164: .newDocumentBuilder();
165: // get DOM
166: Document theDOM = null;
167: theDOM = theDocumentBuilder.parse(URLHelper.make(getURL(),
168: "balancer.xml").openStream());
169: Node balancerNode = theDOM.getDocumentElement();
170:
171: // set service
172: Node serviceNode = XMLHelper.getFirstNamedChild("service",
173: balancerNode);
174: setService(balancer, serviceNode);
175: // set Balancer
176: setBalancer(balancer, balancerNode);
177: } catch (Throwable t) {
178: // t.printStackTrace();
179: throw new BuildException(t);
180: }
181:
182: return balancer;
183: }
184:
185: /**
186: *
187: */
188: public void setService(I_Service aService, Node aNode) {
189: if (aNode == null) {
190: return;
191: } else {
192: // check: is this a proper node?
193: if (!aNode.getNodeName().equals("service")) {
194: throw new IllegalArgumentException(
195: "Node must be null or has to have the nodename balancer: "
196: + aNode.getNodeName());
197: }
198: // set name
199: Node nameNode = XMLHelper.getFirstNamedChild("name", aNode);
200: if (nameNode != null) {
201: aService.setName(trim(XMLHelper
202: .getCharacterData(nameNode)));
203: }
204:
205: // set handlerclass
206: Node handlerClassNode = XMLHelper.getFirstNamedChild(
207: "handler-class", aNode);
208: if (handlerClassNode != null) {
209: aService.setHandlerClassname(trim(XMLHelper
210: .getCharacterData(handlerClassNode)));
211: }
212:
213: // set log-config
214: Node logConfigNode = XMLHelper.getFirstNamedChild(
215: "log-config", aNode);
216: if (logConfigNode != null)
217: setLogConfig(aService, logConfigNode);
218:
219: // set version
220: Node versionNode = XMLHelper.getFirstNamedChild("version",
221: aNode);
222: if (versionNode != null)
223: setVersion(aService, versionNode);
224:
225: // set thread-config
226: Node threadConfigNode = XMLHelper.getFirstNamedChild(
227: "thread-config", aNode);
228: if (threadConfigNode != null)
229: setThreadConfig(aService, threadConfigNode);
230:
231: // listener
232: Enumeration listenerEnum = XMLHelper.namedChilds(
233: "listener", aNode);
234: while (listenerEnum.hasMoreElements()) {
235: setListener(aService, (Node) listenerEnum.nextElement());
236: }
237: }
238: }
239:
240: /**
241: *
242: */
243: public void setVersion(I_Service aService, Node aNode) {
244: if (aNode == null) {
245: return;
246: } else {
247: // check: is this a proper node?
248: if (!aNode.getNodeName().equals("version")) {
249: throw new IllegalArgumentException(
250: "Node must be null or has to have the nodename version: "
251: + aNode.getNodeName());
252: }
253: // set major
254: Node majorNode = XMLHelper.getFirstNamedChild("major",
255: aNode);
256: if (majorNode != null) {
257: try {
258: aService.setMajorVersion(Integer
259: .parseInt(trim(XMLHelper
260: .getCharacterData(majorNode))));
261: } catch (Exception e) {
262: Log.getLog(aService.getName()).log(
263: "Failed to parse majorversion.",
264: C_Log.ERROR);
265: }
266: }
267:
268: // set minor
269: Node minorNode = XMLHelper.getFirstNamedChild("minor",
270: aNode);
271: if (minorNode != null) {
272: try {
273: aService.setMajorVersion(Integer
274: .parseInt(trim(XMLHelper
275: .getCharacterData(minorNode))));
276: } catch (Exception e) {
277: Log.getLog(aService.getName()).log(
278: "Failed to parse minorversion.",
279: C_Log.ERROR);
280: }
281: }
282: }
283: }
284:
285: /**
286: *
287: */
288: public void setLogConfig(I_Service aService, Node aNode) {
289: if (aNode == null) {
290: return;
291: } else {
292: // check: is this a proper node?
293: if (!aNode.getNodeName().equals("log-config")) {
294: throw new IllegalArgumentException(
295: "Node must be null or has to have the nodename log-config: "
296: + aNode.getNodeName());
297: }
298:
299: // default file
300: URL theLogURL = null;
301: try {
302: theLogURL = new URL(getURL(), "balancer.log");
303: } catch (MalformedURLException mfue) {
304: Log.getLog(aService.getName()).log(
305: "Failed to build default logfilename: " + mfue,
306: C_Log.ERROR);
307: }
308:
309: // set file
310: Node fileNode = XMLHelper.getFirstNamedChild("file", aNode);
311: if (fileNode != null) {
312: try {
313: theLogURL = new URL(getURL(), trim(XMLHelper
314: .getCharacterData(fileNode)));
315: } catch (MalformedURLException mfue) {
316: Log.getLog(aService.getName()).log(
317: "Failed to parse log file: " + mfue,
318: C_Log.ERROR);
319: }
320: }
321:
322: // level
323: Node levelNode = XMLHelper.getFirstNamedChild("level",
324: aNode);
325: if (levelNode != null) {
326: try {
327: Log.getLog(aService.getName()).setLevel(
328: Integer.parseInt(trim(XMLHelper
329: .getCharacterData(levelNode))));
330: } catch (Exception e) {
331: Log.getLog(aService.getName()).log(
332: "Failed to parse level.", C_Log.ERROR);
333: }
334: }
335:
336: // buffer size
337: Node bufferSizeNode = XMLHelper.getFirstNamedChild(
338: "buffer-size", aNode);
339: int buffersize = 25;
340: if (bufferSizeNode != null) {
341: try {
342: buffersize = Integer.parseInt(trim(XMLHelper
343: .getCharacterData(bufferSizeNode)));
344: } catch (Exception e) {
345: Log.getLog(aService.getName()).log(
346: "Failed to parse buffersize.", C_Log.ERROR);
347: }
348: }
349:
350: try {
351: LogWriter theLogWriter = new LogFileWriter(
352: PlatformHelper.getOSSpecificPath(theLogURL
353: .getFile()), true, buffersize);
354:
355: Log.getLog(aService.getName()).addI_LogEventListener(
356: theLogWriter);
357: } catch (IOException ioe) {
358: Log.getLog(aService.getName()).log(
359: "Failed to register LogWriter: " + theLogURL,
360: C_Log.ERROR);
361: }
362: }
363: }
364:
365: /**
366: *
367: */
368: public void setThreadConfig(I_Service aService, Node aNode) {
369: if (aNode == null) {
370: return;
371: } else {
372: // check: is this a proper node?
373: if (!aNode.getNodeName().equals("thread-config")) {
374: throw new IllegalArgumentException(
375: "Node must be null or has to have the nodename thread-config: "
376: + aNode.getNodeName());
377: }
378:
379: // set max
380: Node maxNode = XMLHelper.getFirstNamedChild("max", aNode);
381: if (maxNode != null) {
382: try {
383: aService.setMaxHandlerThreads(Integer
384: .parseInt(trim(XMLHelper
385: .getCharacterData(maxNode))));
386: } catch (Exception e) {
387: e.printStackTrace();
388: Log.getLog(aService.getName()).log(
389: "Failed to parse max threads: " + maxNode,
390: C_Log.ERROR);
391: }
392: }
393:
394: // set min
395: Node minNode = XMLHelper.getFirstNamedChild("min", aNode);
396: if (minNode != null) {
397: try {
398: aService.setMinHandlerThreads(Integer
399: .parseInt(trim(XMLHelper
400: .getCharacterData(minNode))));
401: } catch (Exception e) {
402: Log.getLog(aService.getName()).log(
403: "Failed to parse min threads: " + minNode,
404: C_Log.ERROR);
405: e.printStackTrace();
406: }
407: }
408:
409: // set pool-reduction-timeout
410: Node poolReductionTimeoutNode = XMLHelper
411: .getFirstNamedChild("pool-reduction-timeout", aNode);
412: if (poolReductionTimeoutNode != null) {
413: try {
414: aService
415: .setSoTimeout(Integer
416: .parseInt(trim(XMLHelper
417: .getCharacterData(poolReductionTimeoutNode))));
418: } catch (Exception e) {
419: Log.getLog(aService.getName()).log(
420: "Failed to parse poolReductionTimeout.",
421: C_Log.ERROR);
422: }
423: }
424: }
425: }
426:
427: /**
428: *
429: */
430: public void setListener(I_Service aService, Node aNode) {
431: if (aNode == null) {
432: return;
433: } else {
434: // check: is this a proper node?
435: if (!aNode.getNodeName().equals("listener")) {
436: throw new IllegalArgumentException(
437: "Node must be null or has to have the nodename listener: "
438: + aNode.getNodeName());
439: }
440:
441: // make this configurable
442: I_TCPListener listener = new TCPListener();
443:
444: // set port
445: Node portNode = XMLHelper.getFirstNamedChild("port", aNode);
446: if (portNode != null) {
447: try {
448: listener.setPort(Integer.parseInt(trim(XMLHelper
449: .getCharacterData(portNode))));
450: } catch (Exception e) {
451: Log.getLog(aService.getName()).log(
452: "Failed to parse listener port.",
453: C_Log.ERROR);
454: }
455: }
456:
457: // set address
458: Node addressNode = XMLHelper.getFirstNamedChild("address",
459: aNode);
460: if (addressNode != null) {
461: try {
462: listener.setBindAddress(InetAddress
463: .getByName(trim(XMLHelper
464: .getCharacterData(addressNode))));
465: } catch (Exception e) {
466: Log.getLog(aService.getName()).log(
467: "Failed to parse listener address.",
468: C_Log.ERROR);
469: }
470: }
471:
472: // set backlog
473: Node backlogNode = XMLHelper.getFirstNamedChild("backlog",
474: aNode);
475: if (backlogNode != null) {
476: try {
477: listener.setBacklog(Integer.parseInt(trim(XMLHelper
478: .getCharacterData(backlogNode))));
479: } catch (Exception e) {
480: Log.getLog(aService.getName()).log(
481: "Failed to parse listener backlog.",
482: C_Log.ERROR);
483: }
484: }
485:
486: // set name
487: Node nameNode = XMLHelper.getFirstNamedChild("name", aNode);
488: if (nameNode != null) {
489: listener.setName(trim(XMLHelper
490: .getCharacterData(nameNode)));
491: }
492:
493: listener.setService(aService);
494: aService.addListener(listener);
495: }
496: }
497:
498: /**
499: *
500: */
501: public void setBalancer(JoBalancer aBalancer, Node aNode) {
502: if (aNode == null) {
503: return;
504: } else {
505: // check: is this a proper node?
506: if (!aNode.getNodeName().equals("balancer")) {
507: throw new IllegalArgumentException(
508: "Node must be null or has to have the nodename balancer: "
509: + aNode.getNodeName());
510: }
511:
512: // set sticky-timeout (value in min => ms)
513: Node stickyTimeoutNode = XMLHelper.getFirstNamedChild(
514: "sticky-timeout", aNode);
515: if (stickyTimeoutNode != null) {
516: try {
517: aBalancer
518: .setStickyTimeout(1000L * 60L * Long
519: .parseLong(trim(XMLHelper
520: .getCharacterData(stickyTimeoutNode))));
521: } catch (Exception e) {
522: Log.getLog(aBalancer.getName()).log(
523: "Failed to parse sticky-timeout.",
524: C_Log.ERROR);
525: }
526: }
527:
528: // set unavailable-timeout (value in min => ms)
529: Node unavailableTimeoutNode = XMLHelper.getFirstNamedChild(
530: "unavailable-timeout", aNode);
531: if (unavailableTimeoutNode != null) {
532: try {
533: aBalancer
534: .setUnavailableTimeout(1000L * 60L * Long
535: .parseLong(trim(XMLHelper
536: .getCharacterData(unavailableTimeoutNode))));
537: } catch (Exception e) {
538: Log.getLog(aBalancer.getName()).log(
539: "Failed to parse unavailable-timeout.",
540: C_Log.ERROR);
541: }
542: }
543:
544: // server
545: Enumeration serverEnum = XMLHelper.namedChilds("server",
546: aNode);
547: while (serverEnum.hasMoreElements()) {
548: setServer(aBalancer, (Node) serverEnum.nextElement());
549: }
550: }
551: }
552:
553: /**
554: *
555: */
556: public void setServer(JoBalancer aBalancer, Node aNode) {
557: if (aNode == null) {
558: return;
559: } else {
560: // check: is this a proper node?
561: if (!aNode.getNodeName().equals("server")) {
562: throw new IllegalArgumentException(
563: "Node must be null or has to have the nodename server: "
564: + aNode.getNodeName());
565: }
566:
567: InetAddress address = null;
568: int port = 80;
569:
570: // set address
571: Node addressNode = XMLHelper.getFirstNamedChild("address",
572: aNode);
573: if (addressNode != null) {
574: try {
575: address = InetAddress.getByName(trim(XMLHelper
576: .getCharacterData(addressNode)));
577: } catch (Exception e) {
578: Log.getLog(aBalancer.getName()).log(
579: "Failed to resolve server address: " + e,
580: C_Log.ERROR);
581: }
582: }
583:
584: // set port
585: Node portNode = XMLHelper.getFirstNamedChild("port", aNode);
586: if (portNode != null) {
587: try {
588: port = Integer.parseInt(trim(XMLHelper
589: .getCharacterData(portNode)));
590: } catch (Exception e) {
591: Log.getLog(aBalancer.getName())
592: .log("Failed to parse server port.",
593: C_Log.ERROR);
594: }
595: }
596: aBalancer.addServer(new InetAddressPort(address, port));
597: }
598: }
599:
600: /**
601: * Method.
602: *
603: *
604: * @param toTrim
605: *
606: * @return
607: *
608: * @see
609: */
610: private static final String trim(String toTrim) {
611: if (toTrim == null) {
612: return null;
613: }
614:
615: return toTrim.trim();
616: }
617:
618: }
|