Repository: oodt Updated Branches: refs/heads/master 5794ec3bc -> f8e7d9569
wip 1.0 Project: http://git-wip-us.apache.org/repos/asf/oodt/repo Commit: http://git-wip-us.apache.org/repos/asf/oodt/commit/dab58205 Tree: http://git-wip-us.apache.org/repos/asf/oodt/tree/dab58205 Diff: http://git-wip-us.apache.org/repos/asf/oodt/diff/dab58205 Branch: refs/heads/master Commit: dab582059c58ab669c5b3b43a9d6c12989bd2806 Parents: f91720d Author: Radu Manole <manole.v.r...@gmail.com> Authored: Wed Aug 12 01:34:54 2015 +0300 Committer: Radu Manole <manole.v.r...@gmail.com> Committed: Wed Aug 12 01:34:54 2015 +0300 ---------------------------------------------------------------------- commons/pom.xml | 12 + .../org/apache/oodt/commons/AvroExecServer.java | 369 +++++++++++++++++++ .../org/apache/oodt/commons/ExecServer.java | 2 +- .../oodt/commons/AvroMultiServerTest.java | 96 +++++ 4 files changed, 478 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/oodt/blob/dab58205/commons/pom.xml ---------------------------------------------------------------------- diff --git a/commons/pom.xml b/commons/pom.xml index ed5f8ee..3703c12 100644 --- a/commons/pom.xml +++ b/commons/pom.xml @@ -105,6 +105,18 @@ </profile> </profiles> <dependencies> + + <dependency> + <groupId>org.apache.avro</groupId> + <artifactId>avro</artifactId> + <version>1.7.7</version> + </dependency> + <dependency> + <groupId>org.apache.avro</groupId> + <artifactId>avro-ipc</artifactId> + <version>1.7.7</version> + </dependency> + <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> http://git-wip-us.apache.org/repos/asf/oodt/blob/dab58205/commons/src/main/java/org/apache/oodt/commons/AvroExecServer.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/oodt/commons/AvroExecServer.java b/commons/src/main/java/org/apache/oodt/commons/AvroExecServer.java new file mode 100644 index 0000000..6aa5d40 --- /dev/null +++ b/commons/src/main/java/org/apache/oodt/commons/AvroExecServer.java @@ -0,0 +1,369 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.oodt.commons; + +import org.apache.avro.Protocol; +import org.apache.avro.ipc.HttpServer; +import org.apache.avro.ipc.Responder; +import org.apache.avro.ipc.Server; +import org.apache.avro.ipc.generic.GenericResponder; +import org.apache.avro.ipc.specific.SpecificResponder; +import org.apache.oodt.commons.io.Base64EncodingOutputStream; +import org.apache.oodt.commons.util.LogInit; +import org.apache.oodt.commons.util.XML; +import org.apache.xmlrpc.XmlRpcServer; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import javax.naming.Context; +import javax.naming.NamingException; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.rmi.server.RemoteObject; +import java.rmi.server.RemoteRef; +import java.rmi.server.RemoteStub; +import java.util.Date; +import java.util.Iterator; + +public class AvroExecServer { + + /** The configuration. */ + private static Configuration configuration; + + /** The servant. */ + private Object servant; + + + /** Current binder, if any. */ + private static Binder binder; + + /** Object key name. */ + protected String name; + + /** Server's status document. */ + private Document statusDocument; + + /** The <log> element within the status document. */ + private Element logElement; + + /** The XML-RPC interface to this server. */ + private HttpServer server; + + + /** Status DTD Document Type Definition formal public identifier. */ + public static final String STATUS_FPI = "-//JPL//DTD EDA Server Status 1.0"; + + /** Status DTD system identifier. */ + public static final String STATUS_URL = "http://oodt.jpl.nasa.gov/edm-commons/xml/serverStatus.dtd"; + + /** Name of the property that prints the server's IOR or RMI handle. */ + public static final String PRINT_IOR_PROPERTY = "org.apache.oodt.commons.ExecServer.printIOR"; + + /** Name of the property that prevents binding of this object with the naming service. */ + public static final String DISABLE_BINDING = "org.apache.oodt.commons.ExecServer.disableBinding"; + + /** How long to wait before bind attempts, in ms. */ + private static final long REBIND_PERIOD = Long.getLong("org.apache.oodt.commons.ExecServer.rebindPeriod", 30*60*1000).longValue(); + + + protected AvroExecServer(String name) { + this.name = name; + } + + /** Create a new executable server. + * + * @param name Name of the server + * @param className Name of class that implements the server. + * @throws ClassNotFoundException If the class for <var>className</var> can't be found. + * @throws NoSuchMethodException If the constructor for <var>className</var> taking a single <code>ExecServer</code> + * can't be found. + * @throws InstantiationException If the class for <var>className</var> is abstract or is an interface. + * @throws IllegalAccessException If the class for <var>className</var> isn't public. + * @throws InvocationTargetException If an exception occurs in the constructor for <var>className</var>. + * @throws DOMException If the server's status document can't be created. + * @throws UnknownHostException If the local host name can't be determined. + */ + public AvroExecServer(String name, String className) throws ClassNotFoundException, NoSuchMethodException, + InstantiationException, IllegalAccessException, InvocationTargetException, DOMException, UnknownHostException { + this.name = name; + + // Find the class and the required constructor. + Class clazz = Class.forName(className); + Constructor ctor = clazz.getConstructor(new Class[]{ExecServer.class}); + + // Invoke the constructor to create the servant. + servant = ctor.newInstance(new Object[]{this}); + Date startDate = new Date(); + + // Create the XML-RPC interface to this server. + + // I should create avro interface to this server + + Responder responder = new GenericResponder() { + @Override + public Object respond(Protocol.Message message, Object o) throws Exception { + + return null; + } + } + server =new HttpServer(); + server. + +// xmlrpcServer = new XmlRpcServer(); +// xmlrpcServer.addHandler("server", this); + + // Create the server status document. + DocumentType docType = XML.getDOMImplementation().createDocumentType("server", STATUS_FPI, STATUS_URL); + statusDocument = XML.getDOMImplementation().createDocument(/*namespaceURI*/null, "server", docType); + Element serverElement = statusDocument.getDocumentElement(); + XML.add(serverElement, "name", name); + XML.add(serverElement, "class", className); + XML.add(serverElement, "state", "up"); + Element startElement = statusDocument.createElement("start"); + serverElement.appendChild(startElement); + Element userElement = statusDocument.createElement("user"); + startElement.appendChild(userElement); + XML.add(userElement, "name", System.getProperty("user.name", "UNKNOWN")); + XML.add(userElement, "cwd", System.getProperty("user.dir", "UNKNOWN")); + XML.add(userElement, "home", System.getProperty("user.home", "UNKNOWN")); + Element dateElement = statusDocument.createElement("date"); + startElement.appendChild(dateElement); + dateElement.setAttribute("ms", String.valueOf(startDate.getTime())); + dateElement.appendChild(statusDocument.createTextNode(startDate.toString())); + XML.add(startElement, "config", System.getProperty("org.apache.oodt.commons.Configuration.url", "UNKNOWN")); + Element hostElement = statusDocument.createElement("host"); + serverElement.appendChild(hostElement); + XML.add(hostElement, "name", InetAddress.getLocalHost().getHostName()); + Element osElement = statusDocument.createElement("os"); + hostElement.appendChild(osElement); + XML.add(osElement, "name", System.getProperty("os.name", "UNKNOWN")); + XML.add(osElement, "version", System.getProperty("os.version", "UNKNOWN")); + XML.add(osElement, "arch", System.getProperty("os.arch", "UNKNOWN")); + Element vmElement = statusDocument.createElement("vm"); + serverElement.appendChild(vmElement); + XML.add(vmElement, "name", System.getProperty("java.vm.name", "UNKNOWN")); + XML.add(vmElement, "version", System.getProperty("java.version", "UNKNOWN")); + XML.add(vmElement, "classpath", System.getProperty("java.class.path", "UNKNOWN")); + XML.add(vmElement, "extdirs", System.getProperty("java.ext.dirs", "UNKNOWN")); + logElement = statusDocument.createElement("log"); + serverElement.appendChild(logElement); + } + + + public static void runInitializers() throws EDAException { + String initList = System.getProperty("org.apache.oodt.commons.initializers", + System.getProperty("org.apache.oodt.commons.ExecServer.initializers", System.getProperty("initializers", ""))); + for (Iterator i = org.apache.oodt.commons.util.Utility.parseCommaList(initList); i.hasNext();) { + String iname = (String) i.next(); + try { + Class initClass = Class.forName(iname); + Initializer init = (Initializer) initClass.newInstance(); + init.initialize(); + } catch (ClassNotFoundException ex) { + System.err.println("Initializer \"" + iname + "\" not found; aborting"); + throw new EDAException(ex); + } catch (InstantiationException ex) { + System.err.println("Initializer \"" + iname + "\" is abstract; aborting"); + throw new EDAException(ex); + } catch (IllegalAccessException ex) { + System.err.println("Initializer \"" + iname + "\" isn't public; aborting"); + throw new EDAException(ex); + } catch (EDAException ex) { + System.err.println("Initializer \"" + iname + "\" failed: " + ex.getMessage()); + throw new EDAException(ex); + } + } + } + + public static void main(String[] argv) { + if (argv.length < 2) { + System.err.println("Usage: class-name-of-server object-name"); + System.exit(1); + } + + String className = argv[0]; + String name = argv[1]; + + // Enable support of our special URLs, like stdin: + System.setProperty("java.protocol.handler.pkgs", "org.apache.oodt.commons.net.protocol"); + + try { + // Get the configuration. + configuration = Configuration.getConfiguration(); + configuration.mergeProperties(System.getProperties()); + + // Set up the logger. + LogInit.init(System.getProperties(), name); + + // Run initializers + try { + runInitializers(); + } catch (EDAException ex) { + ex.printStackTrace(); + System.exit(1); + } + + // Create it. + final AvroExecServer server = new AvroExecServer(name, className); + + // Print it. + if (Boolean.getBoolean(PRINT_IOR_PROPERTY)) { + if (server.getServant() instanceof RemoteObject) { + RemoteObject remoteObject = (RemoteObject) server.getServant(); + RemoteStub remoteStub = (RemoteStub) RemoteObject.toStub(remoteObject); + RemoteRef ref = remoteStub.getRef(); + System.out.print("RMI:"); + System.out.flush(); + ObjectOutputStream objOut + = new ObjectOutputStream(new Base64EncodingOutputStream(System.out)); + objOut.writeObject(ref); + objOut.flush(); + System.out.println(); + } else { + org.omg.PortableServer.Servant servant=(org.omg.PortableServer.Servant)server.getServant(); + org.omg.CORBA.ORB orb = servant._orb(); + System.out.println(orb.object_to_string(servant._this_object(orb))); + } + System.out.flush(); + } + + // Bind it. + if (!Boolean.getBoolean(DISABLE_BINDING)) { + binder = new Binder(name, server); + binder.start(); + } + + // Prepare for the inevitable + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + server.shutdown0(); + } + }); + + // We're done here. + for (;;) try { + Thread.currentThread().join(); + } catch (InterruptedException ignore) {} + } catch (IOException ex) { + System.err.println("I/O error during initialization: " + ex.getMessage()); + ex.printStackTrace(); + } catch (SAXParseException ex) { + System.err.println("Error in the configuration file at line " + ex.getLineNumber() + ", column " + + ex.getColumnNumber() + ": " + ex.getMessage()); + } catch (SAXException ex) { + System.err.println("Error " + ex.getClass().getName() + " while attempting to parse the configuration" + + " file: " + ex.getMessage()); + } catch (javax.naming.NamingException ex) { + System.err.println("Naming/directory error: " + ex.getClass().getName() + ": " + ex.getMessage()); + } catch (java.lang.reflect.InvocationTargetException ex) { + Throwable target = ex.getTargetException(); + System.err.println("Constructor for \"" + className + "\" threw " + target.getClass().getName() + ": " + + ex.getMessage()); + target.printStackTrace(); + } catch (RuntimeException ex) { + throw ex; + } catch (Exception ex) { + System.err.println("Exception " + ex.getClass().getName() + " initializing server \"" + name + + "\" with class \"" + className + "\": " + ex.getMessage()); + ex.printStackTrace(); + } + System.exit(1); + } + + /** + * Binding thread. + */ + private static class Binder extends Thread { + private boolean keepBinding; + private String name; + private AvroExecServer server; + public Binder(String name, AvroExecServer server) { + super("Binder for " + name); + setDaemon(true); + this.name = name; + this.server = server; + keepBinding = true; + } + public void run() { + while (shouldKeepBinding()) try { + Context objectContext = configuration.getObjectContext(); + objectContext.rebind(name, server.getServant()); + objectContext.close(); + } catch (Throwable ex) { + System.err.println("Exception binding at " + new Date() + "; will keep trying..."); + ex.printStackTrace(); + } finally { + try { + Thread.sleep(REBIND_PERIOD); + } catch (InterruptedException ignore) {} + } + } + public synchronized void stopBinding() { + keepBinding = false; + } + private synchronized boolean shouldKeepBinding() { + return keepBinding; + } + + } + + /** Return the servant for this executable server. + * + * @return The servant. + */ + public Object getServant() { + return servant; + } + + private void shutdown0() { + // Unbind. + if (!Boolean.getBoolean(DISABLE_BINDING)) try { + binder.stopBinding(); + Context objectContext = configuration.getObjectContext(); + objectContext.unbind(getName()); + objectContext.close(); + } catch (NamingException ignore) {} + + // Kill the ORB. YEAH! KILL IT, KILL IT, KIIIIIIIIIIIIIIL IIIIIIIIT!!!!!!!1 + try { + if (servant instanceof org.omg.PortableServer.Servant) { + org.omg.PortableServer.Servant s = (org.omg.PortableServer.Servant) servant; + org.omg.CORBA.ORB orb = s._orb(); + orb.shutdown(false/*=>terminate without waiting for reqs to complete*/); + } + } catch (Throwable ignore) {} + } + + /** Get my name. + * + * @return The name under which I'm registered in teh naming context. + */ + public String getName() { + return name; + } + + +} http://git-wip-us.apache.org/repos/asf/oodt/blob/dab58205/commons/src/main/java/org/apache/oodt/commons/ExecServer.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/oodt/commons/ExecServer.java b/commons/src/main/java/org/apache/oodt/commons/ExecServer.java index 9e8293d..60a6894 100644 --- a/commons/src/main/java/org/apache/oodt/commons/ExecServer.java +++ b/commons/src/main/java/org/apache/oodt/commons/ExecServer.java @@ -459,7 +459,7 @@ public class ExecServer { /** Status DTD formal public identifier. */ public static final String STATUS_FPI = "-//JPL//DTD EDA Server Status 1.0"; - + /** Status DTD system identifier. */ public static final String STATUS_URL = "http://oodt.jpl.nasa.gov/edm-commons/xml/serverStatus.dtd"; http://git-wip-us.apache.org/repos/asf/oodt/blob/dab58205/commons/src/test/java/org/apache/oodt/commons/AvroMultiServerTest.java ---------------------------------------------------------------------- diff --git a/commons/src/test/java/org/apache/oodt/commons/AvroMultiServerTest.java b/commons/src/test/java/org/apache/oodt/commons/AvroMultiServerTest.java new file mode 100644 index 0000000..4904bc5 --- /dev/null +++ b/commons/src/test/java/org/apache/oodt/commons/AvroMultiServerTest.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.oodt.commons; + +import junit.framework.TestCase; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.rmi.server.RemoteObject; + +public class AvroMultiServerTest extends TestCase { + + private InputStream testConfig; + + public AvroMultiServerTest(String name) { + super(name); + } + + protected void setUp() throws Exception { + super.setUp(); + testConfig = getClass().getResourceAsStream("/test-multiserver.xml"); + if (testConfig == null) throw new IOException("Cannot find `test-multiserver.xml'"); + System.setProperty("my.other.setting", "Don't override"); + } + + public void tearDown() throws Exception { + if (testConfig != null) try { + testConfig.close(); + } catch (IOException ignore) {} + System.getProperties().remove("my.setting"); + System.getProperties().remove("my.other.setting"); + super.tearDown(); + } + + public static class Svr1 extends RemoteObject { + public Svr1(ExecServer e) {} + } + public static class Svr2 extends RemoteObject { + public Svr2(ExecServer e) {} + } + public static class Svr3 extends RemoteObject { + public Svr3(ExecServer e) {} + } + public static class Svr4 extends RemoteObject { + public Svr4(ExecServer e) {} + } + + + public void testParsing() throws ParserConfigurationException, SAXException, IOException, ClassNotFoundException, + NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + InputSource is = new InputSource(testConfig); + MultiServer.parseConfig(is); + assertEquals("test.app", MultiServer.getAppName()); + assertEquals(4, MultiServer.getServers().size()); + + MultiServer.Server server = (MultiServer.Server) MultiServer.getServers().get("urn:eda:rmi:Test1"); + assertEquals("org.apache.oodt.commons.MultiServerTest$Svr1", server.getClassName()); + assertEquals(MultiServer.BINDING, server.getBindingBehavior()); + + server = (MultiServer.Server) MultiServer.getServers().get("urn:eda:rmi:Test2"); + assertEquals("org.apache.oodt.commons.MultiServerTest$Svr2", server.getClassName()); + assertEquals(MultiServer.NONBINDING, server.getBindingBehavior()); + + server = (MultiServer.Server) MultiServer.getServers().get("urn:eda:rmi:Test3"); + assertEquals("org.apache.oodt.commons.MultiServerTest$Svr3", server.getClassName()); + assertEquals(MultiServer.REBINDING, server.getBindingBehavior()); + + MultiServer.AutobindingServer s = (MultiServer.AutobindingServer) MultiServer.getServers().get("urn:eda:rmi:Test4"); + assertEquals("org.apache.oodt.commons.MultiServerTest$Svr4", s.getClassName()); + assertEquals(MultiServer.AUTO, s.getBindingBehavior()); + assertEquals(360000L, s.getPeriod()); + + assertEquals("My Value", System.getProperty("my.setting")); + assertEquals("Don't override", System.getProperty("my.other.setting")); + } + +}