From 07b7dfd1a70ba222b899d9813f8c449dbf3b785f Mon Sep 17 00:00:00 2001 From: lresende Date: Wed, 11 Nov 2009 23:07:28 +0000 Subject: Moving 1.x branches git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835124 13f79535-47bb-0310-9956-ffa450edef68 --- .../tuscany/sca/node/impl/ComponentInfoImpl.java | 47 ++ .../sca/node/impl/ComponentManagerServiceImpl.java | 111 +++ .../node/impl/SCADomainAPIServiceProxyImpl.java | 111 +++ .../node/impl/SCADomainEventServiceProxyImpl.java | 117 +++ .../tuscany/sca/node/impl/SCADomainFinderImpl.java | 74 ++ .../tuscany/sca/node/impl/SCADomainProxyImpl.java | 632 ++++++++++++++ .../tuscany/sca/node/impl/SCANodeFactoryImpl.java | 101 +++ .../apache/tuscany/sca/node/impl/SCANodeImpl.java | 937 +++++++++++++++++++++ .../apache/tuscany/sca/node/impl/SCANodeUtil.java | 328 ++++++++ .../tuscany/sca/node/launch/SCANodeLauncher.java | 75 ++ .../management/impl/SCANodeManagerServiceImpl.java | 124 +++ .../node-impl/src/main/resources/node.composite | 79 ++ .../src/main/resources/webroot/index.html | 87 ++ .../node-impl/src/main/resources/webroot/node.png | Bin 0 -> 296 bytes .../node-impl/src/main/resources/webroot/style.css | 176 ++++ .../src/test/java/calculator/AddService.java | 31 + .../src/test/java/calculator/AddServiceImpl.java | 31 + .../test/java/calculator/AddServiceUpdateImpl.java | 31 + .../test/java/calculator/CalculatorService.java | 38 + .../java/calculator/CalculatorServiceImpl.java | 74 ++ .../src/test/java/calculator/DivideService.java | 28 + .../test/java/calculator/DivideServiceImpl.java | 30 + .../src/test/java/calculator/MultiplyService.java | 28 + .../test/java/calculator/MultiplyServiceImpl.java | 30 + .../src/test/java/calculator/SubtractService.java | 31 + .../test/java/calculator/SubtractServiceImpl.java | 31 + .../sca/node/impl/DomainDrivenTestCase.java | 123 +++ .../tuscany/sca/node/impl/NodeDrivenTestCase.java | 161 ++++ .../tuscany/sca/node/impl/NodeMemoryTestCase.java | 85 ++ .../sca/node/impl/StandaloneNodeTestCase.java | 206 +++++ .../calculatordependent/Calculator.composite | 33 + .../META-INF/sca-contribution.xml | 24 + .../calculatorprimary/Calculator.composite | 47 ++ .../META-INF/sca-contribution.xml | 25 + .../src/test/resources/nodeA/Calculator.composite | 44 + .../resources/nodeA/META-INF/sca-contribution.xml | 24 + .../META-INF/sca-deployables/Calculator.composite | 45 + .../META-INF/sca-deployables/Calculator.composite | 32 + .../META-INF/sca-deployables/Calculator.composite | 49 ++ 39 files changed, 4280 insertions(+) create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentInfoImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentManagerServiceImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainAPIServiceProxyImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainEventServiceProxyImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainFinderImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainProxyImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeFactoryImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeUtil.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/launch/SCANodeLauncher.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/management/impl/SCANodeManagerServiceImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/node.composite create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/index.html create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/node.png create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/style.css create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddService.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceUpdateImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorService.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorServiceImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideService.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideServiceImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyService.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyServiceImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractService.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractServiceImpl.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/DomainDrivenTestCase.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeDrivenTestCase.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeMemoryTestCase.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/StandaloneNodeTestCase.java create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/Calculator.composite create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/META-INF/sca-contribution.xml create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/Calculator.composite create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/META-INF/sca-contribution.xml create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/Calculator.composite create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/META-INF/sca-contribution.xml create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeB/META-INF/sca-deployables/Calculator.composite create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeC/META-INF/sca-deployables/Calculator.composite create mode 100644 sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeD/META-INF/sca-deployables/Calculator.composite (limited to 'sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src') diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentInfoImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentInfoImpl.java new file mode 100644 index 0000000000..5e38c6bb81 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentInfoImpl.java @@ -0,0 +1,47 @@ +/* + * 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.tuscany.sca.node.impl; + +import java.io.Serializable; + +import org.apache.tuscany.sca.node.ComponentInfo; + +public class ComponentInfoImpl implements ComponentInfo, Serializable { + + private String name; + private boolean started; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isStarted() { + return started; + } + + public void setStarted(boolean started) { + this.started = started; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentManagerServiceImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentManagerServiceImpl.java new file mode 100644 index 0000000000..3e135c7ebf --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/ComponentManagerServiceImpl.java @@ -0,0 +1,111 @@ +/* + * 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.tuscany.sca.node.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.core.assembly.ActivationException; +import org.apache.tuscany.sca.core.assembly.RuntimeComponentImpl; +import org.apache.tuscany.sca.host.embedded.impl.ReallySmallRuntime; +import org.apache.tuscany.sca.node.ComponentListener; +import org.apache.tuscany.sca.node.ComponentManager; + +public class ComponentManagerServiceImpl implements ComponentManager { + + protected List listeners = new CopyOnWriteArrayList(); + protected String domainURI; + protected String nodeName; + protected Composite nodeComposite; + protected ReallySmallRuntime nodeRuntime; + + public ComponentManagerServiceImpl(String domainURI, String nodeName, Composite nodeComposite, ReallySmallRuntime nodeRuntime) { + this.domainURI = domainURI; + this.nodeName = nodeName; + this.nodeComposite = nodeComposite; + this.nodeRuntime = nodeRuntime; + } + + public void addComponentListener(ComponentListener listener) { + this.listeners.add(listener); + } + + public void removeComponentListener(ComponentListener listener) { + this.listeners.remove(listener); + } + + public Component getComponent(String componentName) { + for (Composite composite: nodeComposite.getIncludes()) { + for (Component component: composite.getComponents()) { + if (component.getName().equals(componentName)) { + return component; + } + } + } + return null; + } + + public List getComponents() { + List components = new ArrayList(); + for (Composite composite: nodeComposite.getIncludes()) { + components.addAll(composite.getComponents()); + } + return components; + } + + public void startComponent(Component component) throws ActivationException { + nodeRuntime.getCompositeActivator().start(component); + notifyComponentStarted(component); + } + + public void stopComponent(Component component) throws ActivationException { + nodeRuntime.getCompositeActivator().stop(component); + notifyComponentStopped(component); + } + + public void notifyComponentStarted(Component component) { + for (ComponentListener listener : listeners) { + try { + listener.componentStarted(component); + } catch (Exception e) { + e.printStackTrace(); // TODO: log + } + } + } + + public void notifyComponentStopped(Component component) { + for (ComponentListener listener : listeners) { + try { + listener.componentStopped(component); + } catch (Exception e) { + e.printStackTrace(); // TODO: log + } + } + } + + public boolean isComponentStarted(Component component) { + RuntimeComponentImpl runtimeComponent = (RuntimeComponentImpl)component; + return runtimeComponent.isStarted(); + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainAPIServiceProxyImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainAPIServiceProxyImpl.java new file mode 100644 index 0000000000..ddb2995d5c --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainAPIServiceProxyImpl.java @@ -0,0 +1,111 @@ +/* + * 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.tuscany.sca.node.impl; + +import java.io.Externalizable; +import java.lang.reflect.UndeclaredThrowableException; +import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.domain.DomainException; +import org.apache.tuscany.sca.domain.SCADomainAPIService; +import org.apache.tuscany.sca.domain.SCADomainEventService; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; + + +/** + * Stores details of services exposed and retrieves details of remote services + * + * @version $Rev: 552343 $ $Date: 2007-09-07 12:41:52 +0100 (Fri, 07 Sep 2007) $ + */ +@Scope("COMPOSITE") +public class SCADomainAPIServiceProxyImpl implements SCADomainAPIService{ + + private final static Logger logger = Logger.getLogger(SCADomainAPIServiceProxyImpl.class.getName()); + + @Reference + protected SCADomainAPIService domainManager; + + public void start() throws DomainException { + domainManager.start(); + } + + public void stop() throws DomainException { + domainManager.stop(); + } + + public void destroyDomain() throws DomainException { + domainManager.destroyDomain(); + } + + public String getURI() { + return domainManager.getURI(); + } + + public void addContribution(String contributionURI, String contributionURL) throws DomainException { + domainManager.addContribution(contributionURI, contributionURL); + } + + public void updateContribution(String contributionURI, String contributionURL) throws DomainException { + domainManager.updateContribution(contributionURI, contributionURL); + } + + public void removeContribution(String contributionURI) throws DomainException { + domainManager.removeContribution(contributionURI); + } + + public void addDeploymentComposite(String contributionURI, String compositeXML) throws DomainException { + domainManager.addDeploymentComposite(contributionURI, compositeXML); + } + + public void updateDeploymentComposite(String contributionURI, String compositeXML) throws DomainException { + domainManager.updateDeploymentComposite(contributionURI, compositeXML); + } + + public void addToDomainLevelComposite(String compositeQName) throws DomainException { + domainManager.addToDomainLevelComposite(compositeQName); + } + + public void removeFromDomainLevelComposite(String compositeQName) throws DomainException { + domainManager.removeFromDomainLevelComposite(compositeQName); + } + + public String getDomainLevelComposite() throws DomainException { + return domainManager.getDomainLevelComposite(); + } + + public String getQNameDefinition(String artifact) throws DomainException { + return domainManager.getQNameDefinition(artifact); + } + + public void startComposite(String compositeQName) throws DomainException { + domainManager.startComposite(compositeQName); + } + + public void stopComposite(String compositeQName) throws DomainException { + domainManager.stopComposite(compositeQName); + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainEventServiceProxyImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainEventServiceProxyImpl.java new file mode 100644 index 0000000000..ac83208c24 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainEventServiceProxyImpl.java @@ -0,0 +1,117 @@ +/* + * 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.tuscany.sca.node.impl; + +import java.io.Externalizable; +import java.lang.reflect.UndeclaredThrowableException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.domain.DomainException; +import org.apache.tuscany.sca.domain.SCADomainEventService; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; + + +/** + * Stores details of services exposed and retrieves details of remote services + * + * @version $Rev: 552343 $ $Date: 2007-09-07 12:41:52 +0100 (Fri, 07 Sep 2007) $ + */ +@Scope("COMPOSITE") +public class SCADomainEventServiceProxyImpl implements SCADomainEventService{ + + private final static Logger logger = Logger.getLogger(SCADomainEventServiceProxyImpl.class.getName()); + + @Property + protected int retryCount = 100; + + @Property + protected int retryInterval = 5000; //ms + + @Reference + protected SCADomainEventService domainManager; + + public void registerNode(String nodeURI, String nodeURL, Externalizable nodeManagerService) throws DomainException { + + // a rety loop is included on node registration in case the node + // comes up before the domain it is registering with + for (int i =0; i < retryCount; i++){ + try { + domainManager.registerNode(nodeURI, nodeURL, nodeManagerService); + break; + } catch(UndeclaredThrowableException ex) { + ex.printStackTrace(); + logger.log(Level.INFO, "Trying to register node " + + nodeURI + + " at endpoint " + + nodeURL); + + } + + try { + Thread.sleep(retryInterval); + } catch(InterruptedException ex) { + } + } + } + + public void unregisterNode(String nodeURI) throws DomainException { + domainManager.unregisterNode(nodeURI); + } + + public void registerNodeStart(String nodeURI) throws DomainException { + domainManager.registerNodeStart(nodeURI); + } + + public void registerNodeStop(String nodeURI) throws DomainException { + domainManager.registerNodeStop(nodeURI); + } + + public void registerContribution(String nodeURI, String contributionURI, String contributionURL) throws DomainException { + domainManager.registerContribution(nodeURI, contributionURI, contributionURL); + } + + public void unregisterContribution(String nodeURI, String contributionURI) throws DomainException { + domainManager.unregisterContribution(nodeURI, contributionURI); + } + + public void registerDomainLevelComposite(String nodeURI, String compositeQNameString) throws DomainException{ + domainManager.registerDomainLevelComposite(nodeURI, compositeQNameString); + } + + public void registerServiceEndpoint(String domainUri, String nodeUri, String serviceName, String bindingName, String URL) throws DomainException { + domainManager.registerServiceEndpoint(domainUri, nodeUri, serviceName, bindingName, URL); + } + + public void unregisterServiceEndpoint(String domainUri, String nodeUri, String serviceName, String bindingName) throws DomainException { + domainManager.unregisterServiceEndpoint(domainUri, nodeUri, serviceName, bindingName); + } + + public String findServiceEndpoint(String domainUri, String serviceName, String bindingName) throws DomainException { + return domainManager.findServiceEndpoint(domainUri, serviceName, bindingName); + } + + public String findServiceNode(String domainUri, String serviceName, String bindingName) throws DomainException { + return domainManager.findServiceNode(domainUri, serviceName, bindingName); + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainFinderImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainFinderImpl.java new file mode 100644 index 0000000000..2e4a0637ef --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainFinderImpl.java @@ -0,0 +1,74 @@ +/* + * 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.tuscany.sca.node.impl; + +import java.util.HashMap; + +import org.apache.tuscany.sca.domain.DomainException; +import org.apache.tuscany.sca.domain.SCADomain; +import org.apache.tuscany.sca.domain.SCADomainSPI; +import org.apache.tuscany.sca.domain.impl.SCADummyNodeImpl; +import org.apache.tuscany.sca.node.SCADomainFinder; +import org.apache.tuscany.sca.node.SCADomainProxySPI; +import org.apache.tuscany.sca.node.SCANode; + +/** + * A finder for SCA domains. + * + * @version $Rev: 580520 $ $Date: 2007-09-29 00:50:25 +0100 (Sat, 29 Sep 2007) $ + */ +public class SCADomainFinderImpl extends SCADomainFinder { + + private static HashMap domains = new HashMap(); + + /** + * Returns a new SCA domain finder instance. + * + * @return a new SCA domain finder + */ + public SCADomainFinderImpl() { + + } + + /** + * Finds an existing SCA domain. + * + * @param domainURI the URI of the domain, this is the endpoint + * URI of the domain administration service + * @return the SCA domain + */ + public SCADomain getSCADomain(String domainURI) throws DomainException { + SCADomain scaDomain = domains.get(domainURI); + + if (scaDomain == null) { + scaDomain = new SCADomainProxyImpl(domainURI); + //domains.put(domainURI, scaDomain); + // TODO - not caching local domains as currently the local domain can + // - only handle one node + // - provides the management endpoint for that node + + // Add the dummy node as there will be no real node in this case + SCANode scaNode = new SCADummyNodeImpl(scaDomain); + ((SCADomainProxyImpl)scaDomain).addNode(scaNode); + } + return scaDomain; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainProxyImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainProxyImpl.java new file mode 100644 index 0000000000..85eb0d4540 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCADomainProxyImpl.java @@ -0,0 +1,632 @@ + /* + * 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.tuscany.sca.node.impl; + +import java.io.ByteArrayOutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.URI; +import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.contribution.DeployedArtifact; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.impl.ModelResolverImpl; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.assembly.ActivationException; +import org.apache.tuscany.sca.core.context.CallableReferenceImpl; +import org.apache.tuscany.sca.domain.DomainException; +import org.apache.tuscany.sca.domain.SCADomainAPIService; +import org.apache.tuscany.sca.domain.SCADomainEventService; +import org.apache.tuscany.sca.domain.impl.SCADomainImpl; +import org.apache.tuscany.sca.domain.impl.SCADummyNodeImpl; +import org.apache.tuscany.sca.domain.model.CompositeModel; +import org.apache.tuscany.sca.host.embedded.impl.ReallySmallRuntime; +import org.apache.tuscany.sca.host.http.ServletHost; +import org.apache.tuscany.sca.host.http.ServletHostExtensionPoint; +import org.apache.tuscany.sca.node.NodeFactoryImpl; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeSPI; +import org.apache.tuscany.sca.node.management.SCANodeManagerInitService; +import org.apache.tuscany.sca.node.management.SCANodeManagerService; +import org.apache.tuscany.sca.node.util.SCAContributionUtil; +import org.osoa.sca.CallableReference; +import org.osoa.sca.ServiceReference; + + +/** + * A local representation of the sca domain running on a single node + * + * @version $Rev$ $Date$ + */ +public class SCADomainProxyImpl extends SCADomainImpl { + + private final static Logger logger = Logger.getLogger(SCADomainProxyImpl.class.getName()); + + // management services + private SCADomainAPIService domainAPIService; + private SCADomainEventService domainEventService; + private SCANodeManagerInitService nodeManagerInitService; + private CallableReferenceImpl nodeManagerService; + + // the local node implementation + private SCANode node; + + // methods defined on the implementation only + + /** + * Creates a domain proxy connected to a wider domain. + * + * @param domainUri - identifies what host and port the domain service is running on, e.g. http://localhost:8081 + * @throws ActivationException + */ + public SCADomainProxyImpl(String domainURI) throws DomainException { + super(domainURI); + } + + /** + * Creates a domain proxy connected to a wider domain. + * + * @param domainUri - identifies what host and port the domain service is running on, e.g. http://localhost:8081 + * @throws ActivationException + */ + public SCADomainProxyImpl(String domainURI, ClassLoader cl) throws DomainException { + super(domainURI); + domainClassLoader = cl; + } + + /** + * Start the composite that connects to the domain manager + */ + protected void init() throws DomainException { + try { + // check where domain uris are urls, they will be used to configure various + // endpoints if they are + URI tmpURI; + try { + tmpURI = new URI(domainModel.getDomainURI()); + domainModel.setDomainURL(tmpURI.toURL().toExternalForm()); + } catch(Exception ex) { + domainModel.setDomainURL(null); + } + + // Check if node has been given a valid domain name to connect to + if (domainModel.getDomainURL() == null) { + logger.log(Level.INFO, "Domain will be started stand-alone as domain URL is not provided"); + } + + } catch(Exception ex) { + throw new DomainException(ex); + } + } + + private void createRuntime() throws DomainException { + try { + // check we don't try to do this twice + if (domainManagementRuntime != null){ + return; + } + + // if there is no node create a runtime otherwise use the runtime from the node + if ((node == null) || + ( (node != null) && (node.getClass().equals(SCADummyNodeImpl.class)))){ + // create a runtime for the domain management services to run on + domainManagementRuntime = new ReallySmallRuntime(domainClassLoader); + domainManagementRuntime.start(); + + String path = URI.create(domainModel.getDomainURI()).getPath(); + + // invent a default URL for the runtime + String host = InetAddress.getLocalHost().getHostName(); + ServerSocket socket = new ServerSocket(0); + int port = socket.getLocalPort(); + socket.close(); + + ServletHostExtensionPoint servletHosts = domainManagementRuntime.getExtensionPointRegistry().getExtensionPoint(ServletHostExtensionPoint.class); + for (ServletHost servletHost: servletHosts.getServletHosts()) { + servletHost.setDefaultPort(port); + if (path != null && path.length() > 0 && !path.equals("/")) { + servletHost.setContextPath(path); + } + } + + // make the node available to the model + // this causes the runtime to start registering binding-sca service endpoints + // with the domain proxy + // TODO - This code is due to be pulled out and combined with the register and + // resolution code that appears in this class + ModelFactoryExtensionPoint factories = domainManagementRuntime.getExtensionPointRegistry().getExtensionPoint(ModelFactoryExtensionPoint.class); + nodeFactory = new NodeFactoryImpl(node); + factories.addFactory(nodeFactory); + + // Create an in-memory domain level management composite + AssemblyFactory assemblyFactory = domainManagementRuntime.getAssemblyFactory(); + domainManagementComposite = assemblyFactory.createComposite(); + domainManagementComposite.setName(new QName(Constants.SCA10_NS, "domainManagement")); + domainManagementComposite.setURI(domainModel.getDomainURI() + "/Management"); + + + } else { + domainManagementRuntime = (ReallySmallRuntime)((SCANodeSPI)node).getNodeRuntime(); + domainManagementComposite = domainManagementRuntime.getCompositeActivator().getDomainComposite(); + + // set the context path for the node + String path = URI.create(node.getURI()).getPath(); + if (path != null && path.length() > 0 && !path.equals("/")) { + ServletHostExtensionPoint servletHosts = domainManagementRuntime.getExtensionPointRegistry().getExtensionPoint(ServletHostExtensionPoint.class); + for (ServletHost servletHost: servletHosts.getServletHosts()) { + servletHost.setContextPath(path); + } + } + } + + // Find the composite that will configure the domain + String domainCompositeName = "node.composite"; + URL contributionURL = SCAContributionUtil.findContributionFromResource(domainClassLoader, domainCompositeName); + + if ( contributionURL != null ){ + logger.log(Level.INFO, "Domain management configured from " + contributionURL); + + // set up a model resolver with the classloader for this domain/node + ModelResolverImpl modelResolver = new ModelResolverImpl(domainClassLoader); + + // add node composite to the management domain + domainManagementContributionService = domainManagementRuntime.getContributionService(); + domainManagementContribution = domainManagementContributionService.contribute("nodedomain", + contributionURL, + modelResolver, + false); + + //update runtime with contribution sca definitions + //this should be done before building the composite + domainManagementRuntime.updateSCADefinitions(domainManagementContributionService.getContributionSCADefinitions()); + + Composite composite = null; + + for (DeployedArtifact artifact: domainManagementContribution.getArtifacts()) { + if (domainCompositeName.equals(artifact.getURI())) { + composite = (Composite)artifact.getModel(); + } + } + + if (composite != null) { + + domainManagementComposite.getIncludes().add(composite); + domainManagementRuntime.buildComposite(composite); + + if (domainModel.getDomainURL() != null) { + URI domainURI = URI.create(domainModel.getDomainURI()); + String domainHost = domainURI.getHost(); + int domainPort = domainURI.getPort(); + + // override any domain URLs in node.composite and replace with the + // domain url provided on start up + for ( Component component : composite.getComponents()){ + for (ComponentReference reference : component.getReferences() ){ + for (Binding binding : reference.getBindings() ) { + String bindingURIString = binding.getURI(); + if (bindingURIString != null) { + URI bindingURI = URI.create(bindingURIString); + String bindingHost = bindingURI.getHost(); + int bindingPort = bindingURI.getPort(); + + if ( bindingPort == 9999){ + // replace the old with the new + bindingURIString = domainURI + bindingURI.getPath() ; + + // set the address back into the NodeManager binding. + binding.setURI(bindingURIString); + } + } + } + } + } + } + + domainManagementRuntime.getCompositeActivator().activate(composite); + domainManagementRuntime.getCompositeActivator().start(composite); + + // get the management components out of the domain so that they + // can be configured/used. + domainAPIService = getService(SCADomainAPIService.class, + "SCADomainAPIServiceProxyComponent", + domainManagementRuntime, + domainManagementComposite); + domainEventService = getService(SCADomainEventService.class, + "SCADomainEventServiceProxyComponent", + domainManagementRuntime, + domainManagementComposite); + + nodeManagerInitService = getService(SCANodeManagerInitService.class, + "SCANodeManagerComponent/SCANodeManagerInitService", + domainManagementRuntime, + domainManagementComposite); + + nodeManagerService = (CallableReferenceImpl) + getServiceReference(SCANodeManagerService.class, + "SCANodeManagerComponent/SCANodeManagerService", + domainManagementRuntime, + domainManagementComposite); + + // add the registered node now that the runtime is started + if ((node != null) && (!node.getClass().equals(SCADummyNodeImpl.class))){ + addNode(); + } + + + } else { + throw new ActivationException("Domain management contribution " + + contributionURL + + " found but could not be loaded"); + } + } else { + throw new ActivationException("Domain management contribution " + + domainCompositeName + + " not found on the classpath"); + } + + } catch(Exception ex) { + throw new DomainException(ex); + } + } + + + public String getComposite(QName compositeQName){ + + Composite composite = null; + for(Composite tmpComposite : domainManagementComposite.getIncludes()){ + if (tmpComposite.getName().equals(compositeQName)){ + composite = tmpComposite; + } + } + + String compositeString = null; + + if (composite != null){ + ExtensionPointRegistry registry = domainManagementRuntime.getExtensionPointRegistry(); + + StAXArtifactProcessorExtensionPoint staxProcessors = + registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + + StAXArtifactProcessor processor = staxProcessors.getProcessor(Composite.class); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(bos); + processor.write(composite, writer); + writer.flush(); + writer.close(); + } catch (Exception ex) { + System.out.println(ex.toString()); + } + + compositeString = bos.toString(); + } + + return compositeString; + } + + // SCADomainEventService methods + + public void addNode(SCANode node) throws DomainException { + this.node = node; + + // add the node into the local domain model + super.registerNode(node.getURI(), node.getURI(), null); + + // the registration of the node with the domain is delayed until + // after the runtime has been started + createRuntime(); + } + + private void addNode() throws DomainException { + + // pass this object into the node manager service + nodeManagerInitService.setNode(node); + + if (domainModel.getDomainURL() != null){ + // add the node to the domain + + try { + // create the node manager endpoint + // TODO - we really need to pass in a callable reference + URI nodeURI = new URI(node.getURI()); + String nodeHost = nodeURI.getHost(); + + if (nodeHost.equals("localhost")){ + nodeHost = InetAddress.getLocalHost().getHostName(); + } + + String nodeManagerURL = nodeURI.getScheme()+ "://" + + nodeHost + ":" + + nodeURI.getPort() + nodeURI.getPath() + "/SCANodeManagerComponent/SCANodeManagerService"; + + // go out and add this node to the wider domain + domainEventService.registerNode(node.getURI(), nodeManagerURL, nodeManagerService); + + } catch(Exception ex) { + logger.log(Level.SEVERE, + "Can't connect to domain manager at: " + + domainModel.getDomainURL()); + throw new DomainException(ex); + } + } + } + + public void removeNode(SCANode node) throws DomainException { + + // remove the node from the local domain model + super.unregisterNode(node.getURI()); + + if (domainModel.getDomainURL() != null){ + + try { + // go out and remove this node to the wider domain + domainEventService.unregisterNode(node.getURI()); + } catch(Exception ex) { + logger.log(Level.SEVERE, + "Can't connect to domain manager at: " + + domainModel.getDomainURL()); + throw new DomainException(ex); + } + } + + // remove this object from the node manager service + nodeManagerInitService.setNode(null); + + this.node = null; + } + + public void registerNodeStart(String nodeURI) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainEventService != null)){ + domainEventService.registerNodeStart(nodeURI); + } + } + + public void registerNodeStop(String nodeURI) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainEventService != null)){ + domainEventService.registerNodeStop(nodeURI); + } + } + + public void registerContribution(String nodeURI, String contributionURI, String contributionURL) throws DomainException { + + if ((domainModel.getDomainURL() != null) && (domainEventService != null)){ + domainEventService.registerContribution(nodeURI, contributionURI, contributionURL); + } + } + + public void unregisterContribution(String nodeURI, String contributionURI) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainEventService != null)) { + domainEventService.unregisterContribution(nodeURI, contributionURI); + } + } + + public void registerDomainLevelComposite(String nodeURI, String compositeQNameString) throws DomainException{ + if ((domainModel.getDomainURL() != null) && (domainEventService != null)) { + domainEventService.registerDomainLevelComposite(nodeURI, compositeQNameString); + } + } + + + public void registerServiceEndpoint(String domainURI, String nodeURI, String serviceName, String bindingName, String URL) throws DomainException { + + //super.registerServiceEndpoint(domainURI, nodeURI, serviceName, bindingName, URL); + + if ((domainModel.getDomainURL() != null) && (domainEventService != null)) { + domainEventService.registerServiceEndpoint(domainURI, nodeURI, serviceName, bindingName, URL); + } + } + + public void unregisterServiceEndpoint(String domainURI, String nodeURI, String serviceName, String bindingName) throws DomainException { + + //super.unregisterServiceEndpoint(domainURI, nodeURI, serviceName, bindingName); + + if ((domainModel.getDomainURL() != null) && (domainEventService != null)) { + domainEventService.unregisterServiceEndpoint(domainURI, nodeURI, serviceName, bindingName); + } + } + + public String findServiceEndpoint(String domainURI, String serviceName, String bindingName) throws DomainException { + + String endpoint = super.findServiceEndpoint(domainURI, serviceName, bindingName); + + if ( (endpoint.equals(SERVICE_NOT_REGISTERED)) && (domainModel.getDomainURL() != null) && (domainEventService != null)){ + endpoint = domainEventService.findServiceEndpoint(domainURI, serviceName, bindingName); + } + + return endpoint; + } + + public String findServiceNode(String domainURI, String serviceName, String bindingName) throws DomainException { + + String nodeName = super.findServiceEndpoint(domainURI, serviceName, bindingName); + + if ( (nodeName.equals(SERVICE_NOT_KNOWN)) && (domainModel.getDomainURL() != null) && (domainEventService != null)){ + nodeName = domainEventService.findServiceNode(domainURI, serviceName, bindingName); + } + + return nodeName; + } + + + // SCADomain API methods + public void start() throws DomainException { + + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.start(); + } else { + logger.log(Level.INFO,"Not connected to domain"); + } + } + + public void stop() throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.stop(); + } else { + logger.log(Level.INFO,"Not connected to domain"); + } + } + + public void destroy() throws DomainException { + + try { + + + if (domainManagementRuntime != null) { + Composite composite = domainManagementComposite.getIncludes().get(0); + + domainManagementRuntime.getCompositeActivator().stop(composite); + domainManagementRuntime.getCompositeActivator().deactivate(composite); + + domainManagementComposite.getIncludes().clear(); + domainManagementRuntime.getContributionService().remove(domainManagementContribution.getURI()); + + domainManagementRuntime.stop(); + + domainManagementRuntime = null; + domainManagementComposite = null; + + domainAPIService = null; + domainEventService = null; + nodeManagerInitService = null; + } + + + } catch (Exception ex) { + throw new DomainException(ex); + } + } + + + public void addContribution(String contributionURI, URL contributionURL) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.addContribution(contributionURI, contributionURL.toString()); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public void updateContribution(String contributionURI, URL contributionURL) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.updateContribution(contributionURI, contributionURL.toString()); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public void removeContribution(String contributionURI) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.removeContribution(contributionURI); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public void addDeploymentComposite(String contributionURI, String compositeXML) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.addDeploymentComposite(contributionURI, compositeXML); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public void updateDeploymentComposite(String contributionURI, String compositeXML) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.updateDeploymentComposite(contributionURI, compositeXML); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public void addToDomainLevelComposite(QName compositeQName) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.addToDomainLevelComposite(compositeQName.toString()); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public void removeFromDomainLevelComposite(QName compositeQName) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.removeFromDomainLevelComposite(compositeQName.toString()); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public String getDomainLevelComposite() throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + return domainAPIService.getDomainLevelComposite(); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public String getQNameDefinition(QName artifact) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + return domainAPIService.getQNameDefinition(artifact.toString()); + } else { + throw new DomainException("Not connected to domain"); + } + } + + public void startComposite(QName compositeQName) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.startComposite(compositeQName.toString()); + } else { + logger.log(Level.INFO,"Not connected to domain"); + } + } + + public void stopComposite(QName compositeQName) throws DomainException { + if ((domainModel.getDomainURL() != null) && (domainAPIService != null)){ + domainAPIService.stopComposite(compositeQName.toString()); + } else { + logger.log(Level.INFO,"Not connected to domain"); + } + } + + public > R cast(B target) throws IllegalArgumentException { + return (R)cast(target, domainManagementRuntime); + } + + public B getService(Class businessInterface, String serviceName) { + return getService( businessInterface, serviceName, domainManagementRuntime, domainManagementComposite); + } + + public ServiceReference getServiceReference(Class businessInterface, String name) { + return getServiceReference(businessInterface, name, domainManagementRuntime, domainManagementComposite); + } +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeFactoryImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeFactoryImpl.java new file mode 100644 index 0000000000..e707b1fbb8 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeFactoryImpl.java @@ -0,0 +1,101 @@ +/* + * 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.tuscany.sca.node.impl; + +import org.apache.tuscany.sca.node.NodeException; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeFactory; + +/** + * A finder for SCA domains. + * + * @version $Rev: 580520 $ $Date: 2007-09-29 00:50:25 +0100 (Sat, 29 Sep 2007) $ + */ +public class SCANodeFactoryImpl extends SCANodeFactory { + + + /** + * Create a new SCA node factory instance. + * + * @return a new SCA node factory + */ + public SCANodeFactoryImpl() { + + } + + /** + * Creates a new SCA node. + * + * @param nodeURI the URI of the node, this URI is used to provide the default + * host and port information for the runtime for situations when bindings + * do provide this information + * @param domainURI the URI of the domain that the node belongs to. This URI is + * used to locate the domain manager on the network + * @return a new SCA node. + */ + public SCANode createSCANode(String physicalNodeURI, String domainURI) throws NodeException { + return new SCANodeImpl(physicalNodeURI, domainURI, null); + } + + /** + * Creates a new SCA node. Many physical nodes may share the same logical URL in load balancing + * and failover scenarios where each node in the group runs the same contribution and + * active composites + * + * @param physicalNodeURI the URI of the node, this URI is used to provide the default + * host and port information for the runtime for situations when bindings + * don't provide this information + * @param domainURI the URI of the domain that the node belongs to. This URI is + * used to locate the domain manager on the network + * @param logicalNodeURI the uri of the node to be used in situations where more than one node + * are grouped together for failover or load balancing scenarios. The logicalNodeURI + * will typically identify the logical node where requests are sent + * @return a new SCA node. + */ + public SCANode createSCANode(String physicalNodeURI, String domainURI, String logicalNodeURI) throws NodeException { + return new SCANodeImpl(physicalNodeURI, domainURI, logicalNodeURI); + } + + /** + * Creates a new SCA node. Many physical nodes may share the same logical URL in load balancing + * and failover scenarios where each node in the group runs the same contribution and + * active composites. Also allows a class loaded to b specified. This is the + * classloader that will be used to load the management application used by the + * node to talk to the domain + * + * @param physicalNodeURI the URI of the node, this URI is used to provide the default + * host and port information for the runtime for situations when bindings + * don't provide this information + * @param domainURI the URI of the domain that the node belongs to. This URI is + * used to locate the domain manager on the network + * @param logicalNodeURI the uri of the node to be used in situations where more than one node + * are grouped together for failover or load balancing scenarios. The logicalNodeURI + * will typically identify the logical node where requests are sent. If null is provided + * no logicalNodeURI is set. + * @param classLoader the class loader to use by default when loading contributions. If null is provided + * the classloader the dervied automatically. + * @return a new SCA node. + */ + public SCANode createSCANode(String physicalNodeURI, String domainURI, String logicalNodeURI, ClassLoader classLoader) throws NodeException { + return new SCANodeImpl(physicalNodeURI, domainURI, logicalNodeURI, classLoader); + } + + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeImpl.java new file mode 100644 index 0000000000..f404daf8d7 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeImpl.java @@ -0,0 +1,937 @@ + /* + * 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.tuscany.sca.node.impl; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; +import org.apache.tuscany.sca.assembly.builder.DomainBuilder; +import org.apache.tuscany.sca.assembly.builder.impl.DomainWireBuilderImpl; +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.DeployedArtifact; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resolver.impl.ModelResolverImpl; +import org.apache.tuscany.sca.contribution.service.ContributionService; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.assembly.ActivationException; +import org.apache.tuscany.sca.databinding.impl.XSDDataTypeConverter.Base64Binary; +import org.apache.tuscany.sca.domain.SCADomain; +import org.apache.tuscany.sca.domain.SCADomainEventService; +import org.apache.tuscany.sca.host.embedded.impl.ReallySmallRuntime; +import org.apache.tuscany.sca.host.http.ServletHost; +import org.apache.tuscany.sca.host.http.ServletHostExtensionPoint; +import org.apache.tuscany.sca.node.NodeException; +import org.apache.tuscany.sca.node.NodeFactoryImpl; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeSPI; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; + +/** + * A local representation of the sca domain running on a single node + * + * @version $Rev: 552343 $ $Date: 2007-09-09 23:54:46 +0100 (Sun, 09 Sep 2007) $ + */ +public class SCANodeImpl implements SCANode, SCANodeSPI { + + private final static Logger logger = Logger.getLogger(SCANodeImpl.class.getName()); + + // class loader used to get application resources + private ClassLoader nodeClassLoader; + + // identity and endpoints for the node and the domain it belongs to + private String nodeURI; + private URL nodeURL; + private String logicalNodeURI; + private String domainURI; + + // The tuscany runtime that does the hard work + private ReallySmallRuntime nodeRuntime; + + // the top level components in this node. A subset of the the domain level composite + private Composite nodeComposite; + + // the domain that the node belongs to. This object acts as a proxy to the domain + private SCADomainProxyImpl scaDomain; + + // the started status of the node + private boolean nodeStarted = false; + + // collection for managing contributions that have been added to the node + private Map contributions = new HashMap(); + private Map composites = new HashMap(); + private Map compositeFiles = new HashMap(); + + private QName nodeManagementCompositeName = new QName("http://tuscany.apache.org/xmlns/tuscany/1.0", "node"); + + // Used to pipe node information into the model + NodeFactoryImpl nodeFactory; + + // domain level wiring + DomainBuilder domainBuilder; + + // methods defined on the implementation only + + /** + * Creates a node connected to a wider domain. To find its place in the domain + * node and domain identifiers must be provided. + * + * @param physicalNodeUri - if this is a url it is assumed that this will be used as root url for management components, e.g. http://localhost:8082 + * @param domainUri - identifies what host and port the domain service is running on, e.g. http://localhost:8081 + * @param logicalNodeURI the uri of the node group. This is the enpoint URI of the head of the + * group of nodes. For example, in load balancing scenarios this will be the loaded balancer itself + * @throws ActivationException + */ + public SCANodeImpl(String physicalNodeURI, String domainURI, String logicalNodeURI) throws NodeException { + this.domainURI = domainURI; + this.nodeURI = physicalNodeURI; + this.logicalNodeURI = logicalNodeURI; + this.nodeClassLoader = Thread.currentThread().getContextClassLoader(); + init(); + } + + /** + * Creates a node connected to a wider domain and allows a classpath to be specified. + * To find its place in the domain node and domain identifiers must be provided. + * + * @param physicalNodeUri - if this is a url it is assumed that this will be used as root url for management components, e.g. http://localhost:8082 + * @param domainUri - identifies what host and port the domain service is running on, e.g. http://localhost:8081 + * @param logicalNodeURI the uri of the node group. This is the enpoint URI of the head of the + * group of nodes. For example, in load balancing scenarios this will be the loaded balancer itself + * @param cl - the ClassLoader to use for loading system resources for the node + * @throws ActivationException + */ + public SCANodeImpl(String physicalNodeURI, String domainURI, String logicalNodeURI, ClassLoader cl) throws NodeException { + this.domainURI = domainURI; + this.nodeURI = nodeURI; + this.logicalNodeURI = logicalNodeURI; + this.nodeClassLoader = cl; + init(); + } + + /** + * Work out if we are representing a domain in memory or can go out to the network to + * get domain information. This all depends on whether the domain URI has been specified + * on construction + */ + private void init() throws NodeException { + try { + + // Generate a unique node URI + if (nodeURI == null) { + + String host = InetAddress.getLocalHost().getHostName(); + ServerSocket socket = new ServerSocket(0); + nodeURI = "http://" + host + ":" + socket.getLocalPort(); + socket.close(); + } + + // check whether node uri is an absolute url, + try { + URI tmpURI = new URI(nodeURI); + nodeURL = tmpURI.toURL(); + } catch(Exception ex) { + throw new NodeException("node uri " + + nodeURI + + " must be a valid url"); + } + + // create a node runtime for the domain contributions to run on + nodeRuntime = new ReallySmallRuntime(nodeClassLoader); + nodeRuntime.start(); + + // get the domain builder + domainBuilder = nodeRuntime.getDomainBuilder(); + + // configure the default port and path for this runtime + int port = URI.create(nodeURI).getPort(); + String path = nodeURL.getPath(); + ServletHostExtensionPoint servletHosts = nodeRuntime.getExtensionPointRegistry().getExtensionPoint(ServletHostExtensionPoint.class); + for (ServletHost servletHost: servletHosts.getServletHosts()) { + servletHost.setDefaultPort(port); + if (path != null && path.length() > 0 && !path.equals("/")) { + servletHost.setContextPath(path); + } + } + + // make the node available to the model + // this causes the runtime to start registering binding-sca service endpoints + // with the domain proxy + // TODO - This code is due to be pulled out and combined with the register and + // resolution code that appears in this class + ModelFactoryExtensionPoint factories = nodeRuntime.getExtensionPointRegistry().getExtensionPoint(ModelFactoryExtensionPoint.class); + nodeFactory = new NodeFactoryImpl(this); + factories.addFactory(nodeFactory); + + // Create an in-memory domain level composite + AssemblyFactory assemblyFactory = nodeRuntime.getAssemblyFactory(); + nodeComposite = assemblyFactory.createComposite(); + nodeComposite.setName(new QName(Constants.SCA10_NS, "node")); + nodeComposite.setURI(nodeURI); + + // add the top level composite into the composite activator + nodeRuntime.getCompositeActivator().setDomainComposite(nodeComposite); + + // create a link to the domain + scaDomain = new SCADomainProxyImpl(domainURI, nodeClassLoader); + + // add the node URI to the domain + scaDomain.addNode(this); + + } catch(NodeException ex) { + throw ex; + } catch(Exception ex) { + throw new NodeException(ex); + } + } + + // temp methods to help integrate with existing code + + public Component getComponent(String componentName) { + for (Composite composite: nodeComposite.getIncludes()) { + for (Component component: composite.getComponents()) { + if (component.getName().equals(componentName)) { + return component; + } + } + } + return null; + } + + public List getComponents() { + List components = new ArrayList(); + for (Composite composite: nodeComposite.getIncludes()) { + components.addAll(composite.getComponents()); + } + return components; + } + + /** + * Stating to think about how a node advertises what it can do. + * Maybe need to turn this round and ask the node to decide whether it + * can process a list of artifacts + * @return + */ + public List getFeatures() { + List featureList = new ArrayList(); + + ExtensionPointRegistry registry = nodeRuntime.getExtensionPointRegistry(); + + // TODO - how to get registered features? + ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class); + + return null; + } + + // SCANode SPI methods + + public Object getNodeRuntime() { + return nodeRuntime; + } + + public void startFromDomain() throws NodeException { + if (!nodeStarted){ + startComposites(); + nodeStarted = true; + } + } + + public void stopFromDomain() throws NodeException { + if (nodeStarted){ + stopComposites(); + nodeStarted = false; + } + } + + public void addContributionFromDomain(String contributionURI, URL contributionURL, ClassLoader contributionClassLoader ) throws NodeException { + + if (nodeStarted){ + throw new NodeException("Can't add contribution " + contributionURI + " when the node is running. Call stop() on the node first"); + } + + if (contributionURI == null){ + throw new NodeException("Contribution URI cannot be null"); + } + + if (contributionURL == null){ + throw new NodeException("Contribution URL cannot be null"); + } + + if (contributions.containsKey(contributionURI)) { + throw new NodeException("Contribution " + contributionURI + " has already been added"); + } + + try { + ModelResolver modelResolver = null; + + // if the contribution is to be resolved using a separate class loader + // then create a new model resolver + if (contributionClassLoader != null) { + modelResolver = new ModelResolverImpl(contributionClassLoader); + } + + // Add the contribution to the node + ContributionService contributionService = nodeRuntime.getContributionService(); + Contribution contribution = contributionService.contribute(contributionURI, + contributionURL, + modelResolver, + false); + + // remember the contribution + contributions.put(contributionURI, contribution); + + // remember all the composites that have been found + for (DeployedArtifact artifact : contribution.getArtifacts()) { + if (artifact.getModel() instanceof Composite) { + Composite composite = (Composite)artifact.getModel(); + composites.put(composite.getName(), composite); + compositeFiles.put(composite.getURI(), composite); + } + } + + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + public void removeContributionFromDomain(String contributionURI) throws NodeException { + + if (nodeStarted){ + throw new NodeException("Can't remove contribution " + contributionURI + " when the node is running. Call stop() on the node first"); + } + + if (contributionURI == null){ + throw new NodeException("Contribution URI cannot be null"); + } + + if (!contributions.containsKey(contributionURI)) { + throw new NodeException("Contribution " + contributionURI + " has not been added"); + } + + try { + + Contribution contribution = contributions.get(contributionURI); + + // remove the local record of composites associated with this contribution + for (DeployedArtifact artifact : contribution.getArtifacts()) { + if (artifact.getModel() instanceof Composite) { + Composite composite = (Composite)artifact.getModel(); + composites.remove(composite.getName()); + compositeFiles.remove(composite.getURI()); + } + } + + // remove the contribution from the contribution service + nodeRuntime.getContributionService().remove(contributionURI); + + // remove any deployed composites from the node level composite + for (Composite composite : contribution.getDeployables()) { + if (nodeComposite.getIncludes().contains(composite)){ + // deactivate it + deactivateComposite(composite); + + // remove it + nodeComposite.getIncludes().remove(composite); + } + } + + // remove the local record of the contribution + contributions.remove(contributionURI); + + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + public void addToDomainLevelCompositeFromDomain(QName compositeQName) throws NodeException { + + if (nodeStarted){ + throw new NodeException("Can't add composite " + compositeQName.toString() + " when the node is running. Call stop() on the node first"); + } + + Composite composite = composites.get(compositeQName); + + if (composite == null) { + throw new NodeException("Composite " + compositeQName.toString() + " not found" ); + } + + // if the named composite is not already in the list then deploy it + if (!nodeComposite.getIncludes().contains(composite)) { + nodeComposite.getIncludes().add(composite); + + try { + // build and activate the model for this composite + activateComposite(composite); + } catch (Exception ex) { + throw new NodeException(ex); + } + } + } + + // SCANode API methods + + public void start() throws NodeException { + if (domainURI != null){ + throw new NodeException("Node is part of domain " + + domainURI + + " so must be starterd from there"); + } else { + startFromDomain(); + } + } + + public void stop() throws NodeException { + if (domainURI != null){ + throw new NodeException("Node is part of domain " + + domainURI + + " so must be stopped from there"); + } else { + stopFromDomain(); + } + } + + public void destroy() throws NodeException { + try { + stopFromDomain(); + + removeAllContributions(); + + // remove the node factory + ModelFactoryExtensionPoint factories = nodeRuntime.getExtensionPointRegistry().getExtensionPoint(ModelFactoryExtensionPoint.class); + factories.removeFactory(nodeFactory); + nodeFactory.setNode(null); + + // unregister the node + scaDomain.removeNode(this); + + // node runtime is stopped by the domain proxy once it has + // removed the management components + scaDomain.destroy(); + + scaDomain = null; + nodeRuntime = null; + contributions = null; + composites = null; + compositeFiles = null; + } catch(NodeException ex) { + throw ex; + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + public String getURI(){ + return nodeURI; + } + + public SCADomain getDomain(){ + return scaDomain; + } + + public void addContribution(String contributionURI, URL contributionURL) throws NodeException { + addContribution(contributionURI, contributionURL, null); + } + + public void addContribution(String contributionURI, URL contributionURL, ClassLoader contributionClassLoader ) throws NodeException { + + try { + addContributionFromDomain(contributionURI, contributionURL, contributionClassLoader); + + // add the contribution to the domain. + scaDomain.registerContribution(nodeURI, contributionURI, contributionURL.toExternalForm()); + + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + public void removeContribution(String contributionURI) throws NodeException { + + try { + removeContributionFromDomain(contributionURI); + + // remove the contribution from the domain. + scaDomain.unregisterContribution(nodeURI, contributionURI); + + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + private void removeAllContributions() throws NodeException { + try { + // copy the keys so we don't get a concurrency error + List keys = new ArrayList(); + + for (String contributionURI : contributions.keySet()){ + keys.add(contributionURI); + } + + // Remove all contributions + for (String contributionURI : keys){ + removeContribution(contributionURI); + } + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + private boolean isDeployable(Composite composite){ + boolean deployable = false; + + for (Contribution contribution : contributions.values()){ + if (contribution.getDeployables().contains(composite)) { + deployable = true; + break; + } + } + + return deployable; + } + + public void addToDomainLevelComposite(QName compositeQName) throws NodeException { + + if (nodeStarted){ + throw new NodeException("Can't add composite " + compositeQName.toString() + " when the node is running. Call stop() on the node first"); + } + + // if no composite name is specified add all deployable composites + // to the domain + if (compositeQName == null){ + for (Composite composite : composites.values()) { + if (!nodeComposite.getIncludes().contains(composite)) { + nodeComposite.getIncludes().add(composite); + + try { + // build and activate the model for this composite + activateComposite(composite); + + // register the composite with the domain + scaDomain.registerDomainLevelComposite(nodeURI, composite.getName().toString()); + + } catch (Exception ex) { + throw new NodeException(ex); + } + + } + } + } else { + Composite composite = composites.get(compositeQName); + + if (composite == null) { + throw new NodeException("Composite " + compositeQName.toString() + " not found" ); + } + + // if the named composite is not already in the list then deploy it + if (!nodeComposite.getIncludes().contains(composite)) { + nodeComposite.getIncludes().add(composite); + + try { + // build and activate the model for this composite + activateComposite(composite); + + // register the composite with the domain + scaDomain.registerDomainLevelComposite(nodeURI, composite.getName().toString()); + + } catch (Exception ex) { + throw new NodeException(ex); + } + } + } + + } + + public void addToDomainLevelComposite(String compositePath) throws NodeException { + + if (compositePath == null){ + addToDomainLevelComposite((QName)null); + } else { + Composite composite = compositeFiles.get(compositePath); + + if (composite != null){ + addToDomainLevelComposite(composite.getName()); + } else { + throw new NodeException("Composite " + compositePath + " not found" ); + } + } + } + + private void activateComposite(Composite composite) throws CompositeBuilderException, ActivationException { + logger.log(Level.INFO, "Building composite: " + composite.getName()); + + // Create the model for the composite + nodeRuntime.getCompositeBuilder().build(composite); + + // activate the composite + nodeRuntime.getCompositeActivator().activate(composite); + + // tell the domain where all the service endpoints are + registerRemoteServices(nodeURI, composite); + } + + private void deactivateComposite(Composite composite) throws CompositeBuilderException, ActivationException { + nodeRuntime.getCompositeActivator().deactivate(composite); + + // no deregistering of endpoints as endpoint handling is going to have to change + } + + + /** + * Configure the default HTTP port for this node. + * The motivation here is to set the default binding on the servlet container + * based on whatever information is available. In particular if no Node URL is + * provided then one of the ports from the first composite is used so that + * some recognizable default is provided for any bindings that are specified + * without URIs + */ + private void configureDefaultPort() { + if (composites.size() == 0){ + return; + } + + Composite composite = nodeComposite.getIncludes().get(1); + + if (composite == null) { + return; + } + + int port = -1; + for (Service service: composite.getServices()) { + for (Binding binding: service.getBindings()) { + String uri = binding.getURI(); + if (uri != null) { + port = URI.create(uri).getPort(); + if (port != -1) { + break; + } + } + } + if (port != -1) { + break; + } + } + for (Component component: composite.getComponents()) { + for (ComponentService service: component.getServices()) { + for (Binding binding: service.getBindings()) { + String uri = binding.getURI(); + if (uri != null) { + port = URI.create(uri).getPort(); + if (port != -1) { + break; + } + } + } + if (port != -1) { + break; + } + } + if (port != -1) { + break; + } + } + + // Then get the port from the node URI + if (port == -1) { + port = URI.create(nodeURI).getPort(); + } + + // Configure the default port + if (port != -1) { + ServletHostExtensionPoint servletHosts = nodeRuntime.getExtensionPointRegistry().getExtensionPoint(ServletHostExtensionPoint.class); + for (ServletHost servletHost: servletHosts.getServletHosts()) { + servletHost.setDefaultPort(port); + } + } + } + + private void startComposites() throws NodeException { + try { + if (nodeComposite.getIncludes().size() == 0 ){ + logger.log(Level.INFO, nodeURI + + " has no composites to start" ); + } else { +/* TODO - moved build/activate back to the point where the + * composite is added. What should I do about this default port business. + * I think that needs to be consumed by the domain model anyhow + // Configure the default server port for the node + configureDefaultPort(); +*/ + + // do cross composite wiring. This is here just in case + // the node has more than one composite and is stand alone + // If the node is not stand alone the domain will do this + if (domainURI == null){ + domainBuilder.wireDomain(nodeComposite); + } + + for (Composite composite : nodeComposite.getIncludes()) { + // don't try and restart the management composite + // they will already have been started by the domain proxy + if (!composite.getName().equals(nodeManagementCompositeName)){ + startComposite(composite); + } + } + } + + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + private void startComposite(Composite composite) throws CompositeBuilderException, ActivationException { + logger.log(Level.INFO, "Starting composite: " + composite.getName()); + + //start the composite + nodeRuntime.getCompositeActivator().start(composite); + } + + private void stopComposites() throws NodeException { + + try { + + for (Composite composite : nodeComposite.getIncludes()) { + // don't try and stop the management composite + // if we do that we can't manage the node + if (!composite.getName().equals(nodeManagementCompositeName)){ + stopComposite(composite); + } + } + + } catch (Exception ex) { + throw new NodeException(ex); + } + } + + private void stopComposite(Composite composite) + throws ActivationException { + logger.log(Level.INFO, "Stopping composite: " + composite.getName()); + nodeRuntime.getCompositeActivator().stop(composite); + } + + private void registerRemoteServices(String nodeURI, Composite composite){ + // Loop through all service binding URIs registering them with the domain + for (Service service: composite.getServices()) { + for (Binding binding: service.getBindings()) { + registerRemoteServiceBinding(nodeURI, null, service, binding); + } + } + + for (Component component: composite.getComponents()) { + for (ComponentService service: component.getServices()) { + for (Binding binding: service.getBindings()) { + registerRemoteServiceBinding(nodeURI, component, service, binding); + } + } + } + } + + private void registerRemoteServiceBinding(String nodeURI, Component component, Service service, Binding binding ){ + if (service.getInterfaceContract().getInterface().isRemotable()) { + String uriString = binding.getURI(); + if (uriString != null) { + + + String serviceName = service.getName(); + + if (component != null){ + serviceName = component.getName() + '/' + serviceName; + } + + try { + scaDomain.registerServiceEndpoint(domainURI, + nodeURI, + serviceName, + binding.getClass().getName(), + uriString); + } catch(Exception ex) { + logger.log(Level.WARNING, + "Unable to register service: " + + domainURI + " " + + nodeURI + " " + + service.getName()+ " " + + binding.getClass().getName() + " " + + uriString); + } + } + } + } + + public void updateComposite(QName compositeQName, String compositeXMLBase64 ) throws NodeException { + logger.log(Level.INFO, "Updating composite " + compositeQName.toString() + + " at node " + nodeURI); + + ByteArrayInputStream bais = new ByteArrayInputStream(Base64Binary.decode(compositeXMLBase64)); + + // find the composite that will be updated + Composite composite = composites.get(compositeQName); + + if (composite == null) { + throw new NodeException("trying to update composite " + compositeQName.toString() + + " which can't be found in node " + nodeURI); + } + + // parse the XML into an composite object + Composite newComposite = null; + + ExtensionPointRegistry registry = nodeRuntime.getExtensionPointRegistry(); + StAXArtifactProcessorExtensionPoint staxProcessors = + registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + + StAXArtifactProcessor processor = staxProcessors.getProcessor(Composite.class); + + try { + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + XMLStreamReader reader = inputFactory.createXMLStreamReader(bais); + newComposite = processor.read(reader); + reader.close(); + } catch (Exception ex) { + throw new NodeException(ex); + } + + + // for each component in the composite compare it against the live component + for (Component newComponent : newComposite.getComponents()){ + for (Component component : composite.getComponents()){ + if (component.getName().equals(newComponent.getName())){ + // compare the component references + for (Reference newReference : newComponent.getReferences()){ + for (Reference reference : component.getReferences()) { + if (reference.getName().equals(newReference.getName())) { + boolean referenceChanged = false; + List removeCandidates = new ArrayList(); + List addCandidates = new ArrayList(); + + removeCandidates.addAll(reference.getBindings()); + + for (Binding newBinding : newReference.getBindings()){ + boolean bindingFound = false; + for (Binding binding : reference.getBindings()){ + // find the matching target service binding + if (binding.getName().equals(newBinding.getName())){ + if ((binding.getURI() != null) && + (newBinding.getURI() != null) && + !binding.getURI().equals(newBinding.getURI())){ + binding.setURI(newBinding.getURI()); + referenceChanged = true; + + logger.log(Level.INFO, "Updating binding " + + component.getName() + + " reference " + + reference.getName() + + " binding " + + binding.getClass().getName() + + " URI " + + binding.getURI()); + } + bindingFound = true; + removeCandidates.remove(binding); + } + } + + if (bindingFound == false){ + addCandidates.add(newBinding); + } + + } + + for (Binding addBinding : addCandidates){ + reference.getBindings().add(addBinding); + referenceChanged = true; + logger.log(Level.INFO, "Adding binding " + + component.getName() + + " reference " + + reference.getName() + + " binding " + + addBinding.getClass().getName() + + " URI " + + addBinding.getURI()); + } + + // remove all of the old bindings + for (Binding removeBinding : removeCandidates){ + reference.getBindings().remove(removeBinding); + referenceChanged = true; + logger.log(Level.INFO, "Removing binding " + + component.getName() + + " reference " + + reference.getName() + + " binding " + + removeBinding.getClass().getName() + + " URI " + + removeBinding.getURI()); + } + + // if the node is running restart the reference and the component that holds it + if (referenceChanged && nodeStarted){ + try { + nodeRuntime.getCompositeActivator().stop((RuntimeComponent)component); + nodeRuntime.getCompositeActivator().deactivate((RuntimeComponent)component, + (RuntimeComponentReference)reference); + nodeRuntime.getCompositeActivator().start((RuntimeComponent)component, + (RuntimeComponentReference)reference); + nodeRuntime.getCompositeActivator().start((RuntimeComponent)component); + + } catch (Exception ex) { + throw new NodeException(ex); + } + + } + } + } + } + + // TODO - compare other parts of the component + } + } + } + + // TODO - Compare other parts of the composite? + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeUtil.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeUtil.java new file mode 100644 index 0000000000..fc8de653da --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/SCANodeUtil.java @@ -0,0 +1,328 @@ +/* + * 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.tuscany.sca.node.impl; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.URI; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.List; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; +import org.apache.tuscany.sca.core.assembly.ActivationException; + + +/** + * Some utility methods for the Node implementation + * + * @version $Rev: 556897 $ $Date: 2007-09-07 12:41:52 +0100 (Fri, 07 Sep 2007) $ + */ +public class SCANodeUtil { + private final static Logger logger = Logger.getLogger(SCANodeUtil.class.getName()); + + /** + * Given a contribution path an array of composite names or neither this method finds + * a suitable contribution to load + * + * @param classLoader + * @param compositePath + * @param composites + * @return the contribution URL + * @throws MalformedURLException + */ +/* + public static URL findContributionURLFromCompositeNameOrPath(ClassLoader classLoader, String contributionPath, String[] composites) + throws MalformedURLException { + + String contributionArtifactPath = null; + URL contributionArtifactURL = null; + + + if (contributionPath != null && contributionPath.length() > 0) { + + //encode spaces as they would cause URISyntaxException + contributionPath = contributionPath.replace(" ", "%20"); + URI contributionURI = URI.create(contributionPath); + if (contributionURI.isAbsolute() || composites.length == 0) { + return new URL(contributionPath); + } else { + // contributionArtifactURL = classLoader.getResource(contributionPath); + // if (contributionArtifactURL == null) { + // throw new IllegalArgumentException("Composite not found: " + contributionArtifactPath); + // } + } + } + + if ( contributionArtifactURL == null){ + if (composites != null && composites.length > 0 && composites[0].length() > 0) { + + // Here the SCADomain was started with a reference to a composite file + contributionArtifactPath = composites[0]; + contributionArtifactURL = classLoader.getResource(contributionArtifactPath); + if (contributionArtifactURL == null) { + throw new IllegalArgumentException("Composite not found: " + contributionArtifactPath); + } + } else { + + // Here the SCANode was started without any reference to a composite file + // We are going to look for an sca-contribution.xml or sca-contribution-generated.xml + + // Look for META-INF/sca-contribution.xml + contributionArtifactPath = Contribution.SCA_CONTRIBUTION_META; + contributionArtifactURL = classLoader.getResource(contributionArtifactPath); + + // Look for META-INF/sca-contribution-generated.xml + if (contributionArtifactURL == null) { + contributionArtifactPath = Contribution.SCA_CONTRIBUTION_GENERATED_META; + contributionArtifactURL = classLoader.getResource(contributionArtifactPath); + } + + // Look for META-INF/sca-deployables directory + if (contributionArtifactURL == null) { + contributionArtifactPath = Contribution.SCA_CONTRIBUTION_DEPLOYABLES; + contributionArtifactURL = classLoader.getResource(contributionArtifactPath); + } + } + } + + if (contributionArtifactURL == null) { + throw new IllegalArgumentException("Can't determine contribution deployables. Either specify a composite file, or use an sca-contribution.xml file to specify the deployables."); + } + + URL contributionURL = null; + // "jar:file://....../something.jar!/a/b/c/app.composite" + try { + String url = contributionArtifactURL.toExternalForm(); + String protocol = contributionArtifactURL.getProtocol(); + if ("file".equals(protocol)) { + // directory contribution + if (url.endsWith(contributionArtifactPath)) { + String location = url.substring(0, url.lastIndexOf(contributionArtifactPath)); + // workaround from evil url/uri form maven + contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL(); + } + + } else if ("jar".equals(protocol)) { + // jar contribution + String location = url.substring(4, url.lastIndexOf("!/")); + // workaround for evil url/uri from maven + contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL(); + } + } catch (MalformedURLException mfe) { + throw new IllegalArgumentException(mfe); + } + + return contributionURL; + } +*/ + /** + * A rather ugly method to find and fix the url of the service, assuming that there + * is one. + * + * we can't get this out of a service reference + * the component itself doesn't know how to get it + * the binding can't to do it automatically as it's not the sca binding + * + * TODO - This would be better done by passing out a serializable reference to service discovery + * but this doesn't work yet + * + * @return node manager url + */ +/* + public static void fixUpNodeServiceUrls(List nodeComponents, URL nodeUrlString) + throws MalformedURLException, UnknownHostException, IOException { + + for(Component component : nodeComponents){ + for (ComponentService service : component.getServices() ){ + for (Binding binding : service.getBindings() ) { + fixUpNodeServiceBindingUrl(binding, nodeUrlString); + } + } + } + } +*/ + /** + * Find and return the URL of the NodeManagerService + * + * @param nodeComponents + * @return + */ +/* + public static String getNodeManagerServiceUrl(List nodeComponents){ + String nodeManagerUrl = null; + + for(Component component : nodeComponents){ + for (ComponentService service : component.getServices() ){ + + if ( service.getName().equals("NodeManagerService")) { + nodeManagerUrl = service.getBindings().get(0).getURI(); + } + } + } + + return nodeManagerUrl; + } +*/ + + /** + * For node management services that use the http(s) protocol then use the node url as the enpoint + * if it has been specified otherwise find a port that isn't in use and make sure the domain name + * is the real domain name + * + * @param binding + * @param nodeURL the URL provided as the identifier of the node + */ +/* + public static void fixUpNodeServiceBindingUrl(Binding binding, URL manualUrl) + throws MalformedURLException, UnknownHostException, IOException { + + String urlString = binding.getURI(); + + // only going to fiddle with bindings that use HTTP protocol + if( (urlString == null) || + ((urlString.startsWith("http") != true ) && + (urlString.startsWith("https") != true )) || + (binding instanceof SCABinding)) { + return; + } + + URL bindingUrl = new URL(urlString); + String originalHost = bindingUrl.getHost(); + String newHost = null; + int originalPort = bindingUrl.getPort(); + int newPort = 0; + + if (manualUrl != null) { + // the required url has been specified manually + newHost = manualUrl.getHost(); + newPort = manualUrl.getPort(); + + if ( newHost.equals("localhost")){ + newHost = InetAddress.getLocalHost().getHostName(); + } + } else { + // discover the host and port information + newHost = InetAddress.getLocalHost().getHostName(); + newPort = findFreePort(originalPort); + } + + // replace the old with the new + urlString = urlString.replace(String.valueOf(originalPort), String.valueOf(newPort)); + urlString = urlString.replace(originalHost, newHost); + + // set the address back into the NodeManager binding. + binding.setURI(urlString); + } +*/ + /** + * Find a port on this machine that isn't in use. + * + * @param startPort + * @return + */ +/* + public static int findFreePort(int startPort) throws IOException + { + ServerSocket socket = new ServerSocket(0); + int port = socket.getLocalPort(); + socket.close(); + return port; + } +*/ + + /** + * For node services that have to talk to the domain fix up the reference URL using the + * provided domain url if it has been provided + * + * @param nodeComponents + * @param domainUrlString + * @throws MalformedURLException + * @throws UnknownHostException + */ +/* + public static void fixUpNodeReferenceUrls(List nodeComponents, URL domainUrl) + throws MalformedURLException, UnknownHostException, ActivationException{ + + for(Component component : nodeComponents){ + for (ComponentReference reference : component.getReferences() ){ + if ( reference.getName().equals("domainManager") || + reference.getName().equals("scaDomainService")) { + for (Binding binding : reference.getBindings() ) { + fixUpNodeReferenceBindingUrl(binding, domainUrl); + } + } + } + } + } +*/ + /** + * For node management references to the domain fix up the binding URLs so that they point + * to the endpoint described in the domainURL + * + * @param binding + * @param nodeURL the URL provided as the identifier of the node + */ +/* + public static void fixUpNodeReferenceBindingUrl(Binding binding, URL manualUrl) + throws MalformedURLException, UnknownHostException, ActivationException{ + + String urlString = binding.getURI(); + + // only going to fiddle with bindings that use HTTP protocol + if( (urlString == null) || + ((urlString.startsWith("http") != true ) && + (urlString.startsWith("https") != true )) || + (binding instanceof SCABinding) ) { + return; + } + + URL bindingUrl = new URL(urlString); + String originalHost = bindingUrl.getHost(); + String newHost = null; + int originalPort = bindingUrl.getPort(); + int newPort = 0; + + if (manualUrl != null) { + // the required url has been specified manually + newHost = manualUrl.getHost(); + newPort = manualUrl.getPort(); + } else { + throw new ActivationException("domain uri can't be null"); + } + + // replace the old with the new + urlString = urlString.replace(String.valueOf(originalPort), String.valueOf(newPort)); + urlString = urlString.replace(originalHost, newHost); + + // set the address back into the NodeManager binding. + binding.setURI(urlString); + } + */ +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/launch/SCANodeLauncher.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/launch/SCANodeLauncher.java new file mode 100644 index 0000000000..0c12d75a25 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/launch/SCANodeLauncher.java @@ -0,0 +1,75 @@ +/* + * 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.tuscany.sca.node.launch; + +import java.io.IOException; +import java.net.URL; + +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeFactory; +import org.apache.tuscany.sca.node.util.SCAContributionUtil; + +public class SCANodeLauncher { + + /** + * @param args + */ + public static void main(String[] args) { + System.out.println("Tuscany starting..."); + + SCANode node = null; + try { + String compositeFile = args[0]; + System.out.println("Composite: " + compositeFile); + + SCANodeFactory nodeFactory = SCANodeFactory.newInstance(); + node = nodeFactory.createSCANode(null, "http://localhost:9999"); + + ClassLoader classLoader = SCANodeLauncher.class.getClassLoader(); + URL contribution = SCAContributionUtil.findContributionFromResource(classLoader, compositeFile); + node.addContribution(compositeFile, contribution); + + node.addToDomainLevelComposite(compositeFile); + + node.start(); + + } catch (Exception e) { + System.err.println("Exception starting node"); + e.printStackTrace(); + System.exit(0); + } + + System.out.println("Node ready..."); + System.out.println("Press enter to shutdown"); + try { + System.in.read(); + } catch (IOException e) { + } + + try { + node.destroy(); + } catch (Exception e) { + System.err.println("Exception stopping node"); + e.printStackTrace(); + } + + System.exit(0); + } +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/management/impl/SCANodeManagerServiceImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/management/impl/SCANodeManagerServiceImpl.java new file mode 100644 index 0000000000..621dd21999 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/management/impl/SCANodeManagerServiceImpl.java @@ -0,0 +1,124 @@ +/* + * 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.tuscany.sca.node.management.impl; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.core.assembly.RuntimeComponentImpl; +import org.apache.tuscany.sca.domain.SCADomain; +import org.apache.tuscany.sca.node.ComponentInfo; +import org.apache.tuscany.sca.node.ComponentManagerService; +import org.apache.tuscany.sca.node.NodeException; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.impl.ComponentInfoImpl; +import org.apache.tuscany.sca.node.impl.SCANodeImpl; +import org.apache.tuscany.sca.node.management.SCANodeManagerInitService; +import org.apache.tuscany.sca.node.management.SCANodeManagerService; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Manages a node implementation + * + * @version $Rev: 552343 $ $Date: 2007-09-11 18:45:36 +0100 (Tue, 11 Sep 2007) $ + */ +@Scope("COMPOSITE") +@Service(interfaces = {SCANodeManagerService.class, SCANodeManagerInitService.class, ComponentManagerService.class}) +public class SCANodeManagerServiceImpl implements SCANodeManagerService, SCANodeManagerInitService, ComponentManagerService { + + private final static Logger logger = Logger.getLogger(SCANodeManagerServiceImpl.class.getName()); + + private SCANodeImpl node; + + + // NodeManagerInitService + + public void setNode(SCANode node) { + this.node = (SCANodeImpl)node; + } + + // SCANodeManagerService methods + + public String getURI() { + return node.getURI(); + } + + public void addContribution(String contributionURI, String contributionURL) throws NodeException { + try { + node.addContributionFromDomain(contributionURI, new URL(contributionURL), null); + } catch (MalformedURLException ex){ + throw new NodeException(ex); + } + } + + public void removeContribution(String contributionURI) throws NodeException { + node.removeContributionFromDomain(contributionURI); + } + + public void addToDomainLevelComposite(String compositeName) throws NodeException { + node.addToDomainLevelCompositeFromDomain(QName.valueOf(compositeName)); + } + + public void start() throws NodeException { + node.startFromDomain(); + } + + public void stop() throws NodeException { + node.stopFromDomain(); + } + + public void destroyNode() throws NodeException { + // do nothing - the domain can't destroy nodes + } + + public void updateComposite(String compositeQName, String compositeXMLBase64 ) throws NodeException { + ((SCANodeImpl)node).updateComposite(QName.valueOf(compositeQName), compositeXMLBase64 ); + } + + // ComponentManagerService + + public List getComponentInfos() { + List componentInfos = new ArrayList(); + for (Component component : node.getComponents()) { + ComponentInfo componentInfo = new ComponentInfoImpl(); + componentInfo.setName(component.getName()); + componentInfo.setStarted(((RuntimeComponentImpl)component).isStarted()); + componentInfos.add(componentInfo); + } + return componentInfos; + } + + public ComponentInfo getComponentInfo(String componentName) { + Component component = node.getComponent(componentName); + ComponentInfo componentInfo = new ComponentInfoImpl(); + componentInfo.setName(component.getName()); + componentInfo.setStarted(((RuntimeComponentImpl)component).isStarted()); + return componentInfo; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/node.composite b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/node.composite new file mode 100644 index 0000000000..137ae72467 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/node.composite @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/index.html b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/index.html new file mode 100644 index 0000000000..e53f353b53 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/index.html @@ -0,0 +1,87 @@ + + + +Apache Tuscany Node + + + + + + + + + + + +

Apache Tuscany Node

+
+ +

Node Uri :

+ + + + + + +
Component NameComponent Is Started
+ +
+ +

+ + + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/node.png b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/node.png new file mode 100644 index 0000000000..fa01e64272 Binary files /dev/null and b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/node.png differ diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/style.css b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/style.css new file mode 100644 index 0000000000..28a4d4540c --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/main/resources/webroot/style.css @@ -0,0 +1,176 @@ +/* + * 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. + */ + +p,table,li,h1,h2,h3 +{ +font-family: verdana, arial, 'sans serif'; +} + +p, h1, h2, h3, table, li, hr +{ +margin-left: 10pt; +} + +table +{ +border-color: black; +border-collapse: separate; +border-spacing: 0px 1px; + +margin-right: 10pt; +margin-left: 10pt; +width: 800px; +} + +.sourceDetailsTable +{ +width: 600px; +} + +tr, td +{ +margin-left: 0pt; +margin-right: 0pt; +padding-left: 10pt; +font-size: 90%; +} + +p,li,th +{ +font-size: 90%; +margin-left: 10pt; +} + +pre +{ +margin-left: 10pt; +} + +body +{ +#ffffff; +} + +h1,h2,h3,hr +{ +color: firebrick; +} + +a:link {COLOR: firebrick;} +a:visited {COLOR: firebrick;} +a:active {COLOR: navy;} + +.link +{ +COLOR: firebrick; +text-decoration: underline; +} + +.clickable +{ +cursor: pointer +} + +.unread_title +{ +font-weight: bold; +} + +.read_title +{ +font-weight: normal; +} + +.summary +{ +color: DimGrey; +} + +.hidden +{ +display: none; +} + +.source_name +{ +width: 600px; +} + +.alert_text +{ +width: 600px; +} + +.alert_data +{ +margin-left: 10px; +width: 800px; +height: 800px; +} + +.source_0 +{ +background-color: LightGreen; +} + +.source_1 +{ +background-color: LightSkyBlue; +} + +.source_2 +{ +background-color: Khaki; +} + +.source_3 +{ +background-color: LightPink; +} + +.source_4 +{ +background-color: Orange; +} + +.source_5 +{ +background-color: LightCoral; +} + +.source_6 +{ +background-color: Orchid; +} + +.source_7 +{ +background-color: Peru; +} + +.source_8 +{ +background-color: SpringGreen; +} + +.source_9 +{ +background-color: LightGrey; +} + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddService.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddService.java new file mode 100644 index 0000000000..797ebb4024 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddService.java @@ -0,0 +1,31 @@ +/* + * 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 calculator; + +import org.osoa.sca.annotations.Remotable; + +/** + * The Add service interface + */ +@Remotable +public interface AddService { + + double add(double n1, double n2); + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceImpl.java new file mode 100644 index 0000000000..1a63d4ff77 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceImpl.java @@ -0,0 +1,31 @@ +/* + * 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 calculator; + +/** + * An implementation of the Add service + */ +public class AddServiceImpl implements AddService { + + public double add(double n1, double n2) { + System.out.println("AddService - add " + n1 + " and " + n2); + return n1 + n2; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceUpdateImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceUpdateImpl.java new file mode 100644 index 0000000000..93486d915e --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/AddServiceUpdateImpl.java @@ -0,0 +1,31 @@ +/* + * 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 calculator; + +/** + * An implementation of the Add service + */ +public class AddServiceUpdateImpl implements AddService { + + public double add(double n1, double n2) { + System.out.println("AddService Update - add " + n1 + " and " + n2); + return n1 + n2; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorService.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorService.java new file mode 100644 index 0000000000..2718ab8772 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorService.java @@ -0,0 +1,38 @@ +/* + * 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 calculator; + +import org.osoa.sca.annotations.Remotable; + + +/** + * The Calculator service interface. + */ +@Remotable +public interface CalculatorService { + + double add(double n1, double n2); + + double subtract(double n1, double n2); + + double multiply(double n1, double n2); + + double divide(double n1, double n2); + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorServiceImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorServiceImpl.java new file mode 100644 index 0000000000..8ee640ed6b --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/CalculatorServiceImpl.java @@ -0,0 +1,74 @@ +/* + * 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 calculator; + +import org.osoa.sca.annotations.Reference; + + +/** + * An implementation of the Calculator service. + */ +public class CalculatorServiceImpl implements CalculatorService { + + private AddService addService; + private SubtractService subtractService; + private MultiplyService multiplyService; + private DivideService divideService; + + @Reference + public void setAddService(AddService addService) { + this.addService = addService; + } + + @Reference + public void setSubtractService(SubtractService subtractService) { + this.subtractService = subtractService; + } + + @Reference + public void setMultiplyService(MultiplyService multiplyService) { + this.multiplyService = multiplyService; + } + + @Reference + public void setDivideService(DivideService divideService) { + this.divideService = divideService; + } + + public double add(double n1, double n2) { + System.out.println("CalculatorService - add " + n1 + " and " + n2); + return addService.add(n1, n2); + } + + public double subtract(double n1, double n2) { + System.out.println("CalculatorService - subtract " + n1 + " and " + n2); + return subtractService.subtract(n1, n2); + } + + public double multiply(double n1, double n2) { + System.out.println("CalculatorService - multiply " + n1 + " and " + n2); + return multiplyService.multiply(n1, n2); + } + + public double divide(double n1, double n2) { + System.out.println("CalculatorService - divide " + n1 + " and " + n2); + return divideService.divide(n1, n2); + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideService.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideService.java new file mode 100644 index 0000000000..ef6a8b375b --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideService.java @@ -0,0 +1,28 @@ +/* + * 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 calculator; + +/** + * The divide service interface + */ +public interface DivideService { + + double divide(double n1, double n2); + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideServiceImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideServiceImpl.java new file mode 100644 index 0000000000..8c33862f6d --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/DivideServiceImpl.java @@ -0,0 +1,30 @@ +/* + * 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 calculator; + +/** + * An implementation of the Divide service. + */ +public class DivideServiceImpl implements DivideService { + + public double divide(double n1, double n2) { + return n1 / n2; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyService.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyService.java new file mode 100644 index 0000000000..db568cc762 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyService.java @@ -0,0 +1,28 @@ +/* + * 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 calculator; + +/** + * The interface for the multiply service + */ +public interface MultiplyService { + + double multiply(double n1, double n2); + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyServiceImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyServiceImpl.java new file mode 100644 index 0000000000..c7fbc73c00 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/MultiplyServiceImpl.java @@ -0,0 +1,30 @@ +/* + * 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 calculator; + +/** + * An implementation of the Multiply service. + */ +public class MultiplyServiceImpl implements MultiplyService { + + public double multiply(double n1, double n2) { + return n1 * n2; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractService.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractService.java new file mode 100644 index 0000000000..615320e670 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractService.java @@ -0,0 +1,31 @@ +/* + * 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 calculator; + +import org.osoa.sca.annotations.Remotable; + +/** + * The interface for the multiply service + */ +@Remotable +public interface SubtractService { + + double subtract(double n1, double n2); + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractServiceImpl.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractServiceImpl.java new file mode 100644 index 0000000000..abf2777c7d --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/calculator/SubtractServiceImpl.java @@ -0,0 +1,31 @@ +/* + * 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 calculator; + +/** + * An implementation of the subtract service. + */ +public class SubtractServiceImpl implements SubtractService { + + public double subtract(double n1, double n2) { + System.out.println("SubtractService - subtract " + n1 + " and " + n2); + return n1 - n2; + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/DomainDrivenTestCase.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/DomainDrivenTestCase.java new file mode 100644 index 0000000000..743161d856 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/DomainDrivenTestCase.java @@ -0,0 +1,123 @@ +/* + * 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.tuscany.sca.node.impl; + + +import javax.xml.namespace.QName; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.domain.SCADomain; +import org.apache.tuscany.sca.domain.SCADomainFactory; +import org.apache.tuscany.sca.node.SCADomainFinder; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import calculator.AddService; +import calculator.CalculatorService; + +/** + * Runs a distributed domain in a single VM by using and in memory + * implementation of the distributed domain + */ +public class DomainDrivenTestCase { + + private static SCADomain domain; + private static SCANode nodeA; + private static SCANode nodeB; + private static SCANode nodeC; + private static CalculatorService calculatorServiceA; + private static CalculatorService calculatorServiceB; + private static AddService addServiceB; + + @BeforeClass + public static void init() throws Exception { + + try { + System.out.println("Setting up domain"); + + SCADomainFactory domainFactory = SCADomainFactory.newInstance(); + domain = domainFactory.createSCADomain("http://localhost:9999"); + + System.out.println("Setting up calculator nodes"); + + ClassLoader cl = DomainDrivenTestCase.class.getClassLoader(); + + SCANodeFactory nodeFactory = SCANodeFactory.newInstance(); + + nodeA = nodeFactory.createSCANode("http://localhost:8100/nodeA", "http://localhost:9999"); + nodeB = nodeFactory.createSCANode("http://localhost:8200/nodeB", "http://localhost:9999"); + nodeC = nodeFactory.createSCANode("http://localhost:8300/nodeC", "http://localhost:9999"); + + domain.addContribution("nodeA", cl.getResource("nodeA/")); + domain.addContribution("nodeB", cl.getResource("nodeB/")); + domain.addContribution("nodeC", cl.getResource("nodeC/")); + + domain.addToDomainLevelComposite(new QName("http://sample", "CalculatorA")); + domain.addToDomainLevelComposite(new QName("http://sample", "CalculatorB")); + domain.addToDomainLevelComposite(new QName("http://sample", "CalculatorC")); + + domain.start(); + + calculatorServiceA = domain.getService(CalculatorService.class, "CalculatorServiceComponentA"); + calculatorServiceB = domain.getService(CalculatorService.class, "CalculatorServiceComponentB"); + + } catch(Exception ex){ + ex.printStackTrace(); + } + + } + + @AfterClass + public static void destroy() throws Exception { + // stop the domain + domain.stop(); + + // destroy the nodes + nodeA.destroy(); + nodeB.destroy(); + nodeC.destroy(); + + // destroy the domain + domain.destroy(); + } + + //@Test + public void testKeepServerRunning() throws Exception { + System.out.println("press enter to continue"); + System.in.read(); + } + + @Test + public void testCalculator() throws Exception { + // Calculate + Assert.assertEquals(calculatorServiceA.add(3, 2), 5.0); + Assert.assertEquals(calculatorServiceA.subtract(3, 2), 1.0); + Assert.assertEquals(calculatorServiceA.multiply(3, 2), 6.0); + Assert.assertEquals(calculatorServiceA.divide(3, 2), 1.5); + Assert.assertEquals(calculatorServiceB.add(3, 2), 5.0); + Assert.assertEquals(calculatorServiceB.subtract(3, 2), 1.0); + Assert.assertEquals(calculatorServiceB.multiply(3, 2), 6.0); + Assert.assertEquals(calculatorServiceB.divide(3, 2), 1.5); + } +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeDrivenTestCase.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeDrivenTestCase.java new file mode 100644 index 0000000000..cd3af4b36d --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeDrivenTestCase.java @@ -0,0 +1,161 @@ +/* + * 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.tuscany.sca.node.impl; + + +import javax.xml.namespace.QName; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.domain.SCADomain; +import org.apache.tuscany.sca.domain.SCADomainFactory; +import org.apache.tuscany.sca.domain.impl.SCADomainImpl; +import org.apache.tuscany.sca.node.SCADomainFinder; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import calculator.AddService; +import calculator.CalculatorService; + +/** + * Runs a distributed domain in a single VM by using and in memory + * implementation of the distributed domain + */ +public class NodeDrivenTestCase { + + private static SCADomain domain; + private static SCANode nodeA; + private static SCANode nodeB; + private static SCANode nodeC; + private static SCADomain domainProxy; + private static CalculatorService calculatorServiceA; + private static CalculatorService calculatorServiceB; + private static AddService addServiceBDomainFinder; + private static AddService addServiceBDomainProxy; + private static AddService addServiceBDomain; + + @BeforeClass + public static void init() throws Exception { + + try { + System.out.println("Setting up domain"); + + SCADomainFactory domainFactory = SCADomainFactory.newInstance(); + domain= domainFactory.createSCADomain("http://localhost:9999"); + + System.out.println("Setting up calculator nodes"); + + ClassLoader cl = NodeDrivenTestCase.class.getClassLoader(); + + SCANodeFactory nodeFactory = SCANodeFactory.newInstance(); + + // sca-contribution.xml test + nodeA = nodeFactory.createSCANode("http://localhost:8100/nodeA", "http://localhost:9999"); + nodeA.addContribution("nodeA", cl.getResource("nodeA/")); + nodeA.addToDomainLevelComposite(new QName("http://sample", "CalculatorA")); + + // sca-deployables test + nodeB = nodeFactory.createSCANode("http://localhost:8200/nodeB", "http://localhost:9999"); + nodeB.addContribution("nodeB", cl.getResource("nodeB/")); + nodeB.addToDomainLevelComposite(new QName("http://sample", "CalculatorB")); + + // sca-deployables test + nodeC = nodeFactory.createSCANode("http://localhost:8300/nodeC", "http://localhost:9999"); + nodeC.addContribution("nodeC", cl.getResource("nodeC/")); + nodeC.addToDomainLevelComposite(new QName("http://sample", "CalculatorC")); + nodeC.addToDomainLevelComposite(new QName("http://sample", "CalculatorC")); + + // start the domain + domain.start(); + + } catch(Exception ex){ + ex.printStackTrace(); + } + + } + + @AfterClass + public static void destroy() throws Exception { + // stop the domain + domain.stop(); + + // destroy the nodes + nodeA.destroy(); + nodeB.destroy(); + nodeC.destroy(); + + // destroy the domain + domain.destroy(); + } + + //@Test + public void testKeepServerRunning() throws Exception { + System.out.println("press enter to continue"); + System.in.read(); + } + + @Test + public void testDomainProxyNode() throws Exception { + // the domain proxy associated with each node used to get local services + calculatorServiceA = nodeA.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentA"); + calculatorServiceB = nodeB.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentB"); + + // Calculate + Assert.assertEquals(calculatorServiceA.add(3, 2), 5.0); + Assert.assertEquals(calculatorServiceA.subtract(3, 2), 1.0); + Assert.assertEquals(calculatorServiceA.multiply(3, 2), 6.0); + Assert.assertEquals(calculatorServiceA.divide(3, 2), 1.5); + Assert.assertEquals(calculatorServiceB.add(3, 2), 5.0); + Assert.assertEquals(calculatorServiceB.subtract(3, 2), 1.0); + Assert.assertEquals(calculatorServiceB.multiply(3, 2), 6.0); + Assert.assertEquals(calculatorServiceB.divide(3, 2), 1.5); + + // the domain proxy associate with each node used to get remote services + addServiceBDomainProxy = nodeA.getDomain().getService(AddService.class, "AddServiceComponentB"); + + Assert.assertEquals(addServiceBDomainProxy.add(3, 2), 5.0); + } + + @Test + public void testDomain() throws Exception { + // the domain itself + addServiceBDomain = domain.getService(AddService.class, "AddServiceComponentB"); + + System.out.println(((SCADomainProxyImpl)nodeA.getDomain()).getComposite(new QName("http://sample", "CalculatorA"))); + + Assert.assertEquals(addServiceBDomain.add(3, 2), 5.0); + } + + @Test + public void testDomainProxyFinder() throws Exception { + // the domain proxy retrieved via the domain finder + SCADomainFinder domainFinder = SCADomainFinder.newInstance(); + domainProxy = domainFinder.getSCADomain("http://localhost:9999"); + addServiceBDomainFinder = domainProxy.getService(AddService.class, "AddServiceComponentB"); + + Assert.assertEquals(addServiceBDomainFinder.add(3, 2), 5.0); + + System.out.println(domainProxy.getDomainLevelComposite()); + } + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeMemoryTestCase.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeMemoryTestCase.java new file mode 100644 index 0000000000..fb223f2736 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeMemoryTestCase.java @@ -0,0 +1,85 @@ +/* + * 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.tuscany.sca.node.impl; + + +import javax.xml.namespace.QName; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.domain.SCADomain; +import org.apache.tuscany.sca.domain.SCADomainFactory; +import org.apache.tuscany.sca.node.SCADomainFinder; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import calculator.AddService; +import calculator.CalculatorService; +import calculator.SubtractService; + +/** + * Runs a distributed domain in a single VM by using and in memory + * implementation of the distributed domain. The test repeatedly + * creates and destroys the node to see if memory is being leaked. + * Looking for leaked memory is a manual task. + */ +public class NodeMemoryTestCase { + + @Test + public void testDoNothing() throws Exception { + + } + + //@Test + public void testNodeMemoryUseage() throws Exception { + + ClassLoader cl = NodeMemoryTestCase.class.getClassLoader(); + SCANodeFactory nodeFactory; + SCANode node; + CalculatorService calculatorServiceB; + SubtractService subtractServiceC; + + for(int i=0; i < 40; i++) { + + nodeFactory = SCANodeFactory.newInstance(); + node = nodeFactory.createSCANode("http://localhost:8200/node", null); + node.addContribution("nodeB", cl.getResource("nodeB/")); + node.addContribution("nodeC", cl.getResource("nodeC/")); + node.addToDomainLevelComposite(new QName("http://sample", "CalculatorB")); + node.addToDomainLevelComposite(new QName("http://sample", "CalculatorC")); + node.start(); + + calculatorServiceB = node.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentB"); + subtractServiceC = node.getDomain().getService(SubtractService.class, "SubtractServiceComponentC"); + + for(int j=0; j < 20; j++){ + Assert.assertEquals(calculatorServiceB.subtract(3, 2), 1.0); + Assert.assertEquals(subtractServiceC.subtract(3, 2), 1.0); + } + + node.destroy(); + } + + //com.ibm.jvm.Dump.HeapDump(); + } +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/StandaloneNodeTestCase.java b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/StandaloneNodeTestCase.java new file mode 100644 index 0000000000..b2906e4aed --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/StandaloneNodeTestCase.java @@ -0,0 +1,206 @@ +/* + * 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.tuscany.sca.node.impl; + + +import javax.xml.namespace.QName; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.domain.SCADomain; +import org.apache.tuscany.sca.domain.SCADomainFactory; +import org.apache.tuscany.sca.node.SCADomainFinder; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import calculator.AddService; +import calculator.CalculatorService; +import calculator.SubtractService; + +/** + * Runs a distributed domain in a single VM by using and in memory + * implementation of the distributed domain + */ +public class StandaloneNodeTestCase { + + private static SCANodeFactory nodeFactory; + private static SCANode node; + private static CalculatorService calculatorServiceA; + private static CalculatorService calculatorServiceB; + private static CalculatorService calculatorServiceD; + private static AddService addServiceD; + private static SubtractService subtractServiceC; + private static ClassLoader cl; + + + @BeforeClass + public static void init() throws Exception { + + try { + System.out.println("Setting up add node"); + + cl = StandaloneNodeTestCase.class.getClassLoader(); + nodeFactory = SCANodeFactory.newInstance(); + + } catch(Exception ex){ + System.err.println(ex.toString()); + } + + } + + @AfterClass + public static void destroy() throws Exception { + // stop the node + node.destroy(); + } + + + @Test + public void testAddContributionAndStartNode() throws Exception { + node = nodeFactory.createSCANode("http://localhost:8100/node", null); + node.addContribution("nodeC", cl.getResource("nodeC/")); + node.addToDomainLevelComposite(new QName("http://sample", "CalculatorC")); + node.start(); + + // get a reference to various services in the node + subtractServiceC = node.getDomain().getService(SubtractService.class, "SubtractServiceComponentC"); + } + + @Test + public void testSubtract() throws Exception { + Assert.assertEquals(subtractServiceC.subtract(3, 2), 1.0); + } + + //@Test + public void testKeepServerRunning1() throws Exception { + System.out.println("press enter to continue"); + System.in.read(); + } + + @Test + public void testStopNode() throws Exception { + node.stop(); + try { + subtractServiceC.subtract(3, 2); +// TODO - stopping the node doesn't actually stop the local wires? +// Assert.fail(); + } catch (Exception ex) { + // System.out.println(ex.toString()); + } + } + + @Test + public void testAddOtherContributionsAndStartNode() throws Exception { + node.addContribution("nodeB", cl.getResource("nodeB/")); + node.addToDomainLevelComposite(new QName("http://sample", "CalculatorB")); + node.addContribution("nodeD", cl.getResource("nodeD/")); + node.addToDomainLevelComposite(new QName("http://sample", "CalculatorD")); + node.start(); + subtractServiceC = node.getDomain().getService(SubtractService.class, "SubtractServiceComponentC"); + calculatorServiceD = node.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentD"); + calculatorServiceB = node.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentB"); + addServiceD = node.getDomain().getService(AddService.class, "AddServiceComponentD"); + + } + + //@Test + public void testKeepServerRunning2() throws Exception { + System.out.println("press enter to continue"); + System.in.read(); + } + + @Test + public void testCalculate() throws Exception { + // Calculate + Assert.assertEquals(calculatorServiceB.add(3, 2), 5.0); + Assert.assertEquals(calculatorServiceB.subtract(3, 2), 1.0); + Assert.assertEquals(calculatorServiceB.multiply(3, 2), 6.0); + Assert.assertEquals(calculatorServiceB.divide(3, 2), 1.5); + Assert.assertEquals(calculatorServiceD.add(3, 2), 5.0); + Assert.assertEquals(calculatorServiceD.subtract(3, 2), 1.0); + Assert.assertEquals(calculatorServiceD.multiply(3, 2), 6.0); + Assert.assertEquals(calculatorServiceD.divide(3, 2), 1.5); + Assert.assertEquals(addServiceD.add(3, 2), 5.0); + Assert.assertEquals(subtractServiceC.subtract(3, 2), 1.0); + + } + + @Test + public void testRemoveContribution() throws Exception { + node.stop(); + node.removeContribution("nodeD"); + + try { + calculatorServiceD.add(3, 2); + Assert.fail(); + } catch (Exception ex) { + // System.out.println(ex.toString()); + } + + calculatorServiceD = node.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentD"); + + try { + Assert.assertEquals(calculatorServiceD.add(3, 2), 5.0); + Assert.fail(); + } catch (Exception ex) { + // System.out.println(ex.toString()); + } + + } + + @Test + public void testAddContributionBackAgain() throws Exception { + + node.addContribution("nodeD", cl.getResource("nodeD/")); + node.addToDomainLevelComposite(new QName("http://sample", "CalculatorD")); + node.start(); + + calculatorServiceD = node.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentD"); + + Assert.assertEquals(calculatorServiceD.add(3, 2), 5.0); + + // stop and remove all the contributions to date + node.stop(); + node.removeContribution("nodeB"); + node.removeContribution("nodeC"); + node.removeContribution("nodeD"); + } + + @Test + public void testAddDepdendentContributions() throws Exception { + node = nodeFactory.createSCANode("http://localhost:8200/node", null); + + // add one contribution that depends on another + node.addContribution("dependent", cl.getResource("calculatordependent/")); + node.addContribution("primary", cl.getResource("calculatorprimary/")); + node.addToDomainLevelComposite(new QName("http://primary", "CalculatorA")); + node.start(); + calculatorServiceA = node.getDomain().getService(CalculatorService.class, "CalculatorServiceComponentA"); + Assert.assertEquals(calculatorServiceA.add(3, 2), 5.0); + Assert.assertEquals(calculatorServiceA.subtract(3, 2), 1.0); + Assert.assertEquals(calculatorServiceA.multiply(3, 2), 6.0); + Assert.assertEquals(calculatorServiceA.divide(3, 2), 1.5); + } + + +} diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/Calculator.composite b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/Calculator.composite new file mode 100644 index 0000000000..538ad2e4c8 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/Calculator.composite @@ -0,0 +1,33 @@ + + + + + + + + + + + + + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/META-INF/sca-contribution.xml b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/META-INF/sca-contribution.xml new file mode 100644 index 0000000000..8264a8243f --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatordependent/META-INF/sca-contribution.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/Calculator.composite b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/Calculator.composite new file mode 100644 index 0000000000..c120fed3ca --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/Calculator.composite @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/META-INF/sca-contribution.xml b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/META-INF/sca-contribution.xml new file mode 100644 index 0000000000..e53c14a651 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/calculatorprimary/META-INF/sca-contribution.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/Calculator.composite b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/Calculator.composite new file mode 100644 index 0000000000..534e1a29af --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/Calculator.composite @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/META-INF/sca-contribution.xml b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/META-INF/sca-contribution.xml new file mode 100644 index 0000000000..1b1c0291e2 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeA/META-INF/sca-contribution.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeB/META-INF/sca-deployables/Calculator.composite b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeB/META-INF/sca-deployables/Calculator.composite new file mode 100644 index 0000000000..bdb89803d1 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeB/META-INF/sca-deployables/Calculator.composite @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeC/META-INF/sca-deployables/Calculator.composite b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeC/META-INF/sca-deployables/Calculator.composite new file mode 100644 index 0000000000..c5af8dd3cc --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeC/META-INF/sca-deployables/Calculator.composite @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeD/META-INF/sca-deployables/Calculator.composite b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeD/META-INF/sca-deployables/Calculator.composite new file mode 100644 index 0000000000..119c52cbf8 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.1/modules/node-impl/src/test/resources/nodeD/META-INF/sca-deployables/Calculator.composite @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3