From 681e195552e16021ebba42fcf56bad2aa6fddc67 Mon Sep 17 00:00:00 2001 From: rfeng Date: Fri, 9 Oct 2009 19:59:43 +0000 Subject: Refactor the runtime build logic into EndpointReferenceBinder Refactor the endpoint-wrapper into domainRegistryFactory that delegates to endpoint registry implementations by the scheme Improve/workaround the monitor so that it can be shared by multiple nodes (We need a better design for this) git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@823672 13f79535-47bb-0310-9956-ffa450edef68 --- .../assembly/builder/EndpointReferenceBuilder.java | 55 - .../tuscany/sca/context/CompositeContext.java | 7 + .../tuscany/sca/runtime/CompositeActivator.java | 12 +- .../tuscany/sca/runtime/DomainRegistryFactory.java | 46 + .../sca/runtime/EndpointReferenceBinder.java | 42 + .../core/assembly/impl/CompositeActivatorImpl.java | 34 +- .../impl/EndpointReferenceBuilderImpl.java | 311 ----- .../core/assembly/impl/EndpointRegistryImpl.java | 150 +-- .../sca/core/assembly/impl/RuntimeWireImpl.java | 32 +- .../core/context/impl/ComponentContextImpl.java | 15 +- .../core/runtime/DefaultDomainRegistryFactory.java | 157 +++ .../runtime/impl/EndpointReferenceBinderImpl.java | 299 +++++ ...org.apache.tuscany.sca.assembly.AssemblyFactory | 18 + ...y.sca.assembly.builder.EndpointReferenceBuilder | 18 - ...pache.tuscany.sca.runtime.DomainRegistryFactory | 17 + ...che.tuscany.sca.runtime.EndpointReferenceBinder | 17 + java/sca/modules/domain-node/META-INF/MANIFEST.MF | 1 + java/sca/modules/domain-node/pom.xml | 6 - .../apache/tuscany/sca/domain/node/DomainNode.java | 28 +- .../sca/domain/node/StopStartNodesTestCase.java | 2 - .../modules/endpoint-tribes/META-INF/MANIFEST.MF | 1 + .../tribes/ReplicatedEndpointRegistry.java | 60 +- .../sca/extensibility/ServiceDiscovery.java | 45 + .../extensibility/impl/InvalidSyntaxException.java | 86 ++ .../tuscany/sca/extensibility/impl/LDAPFilter.java | 1355 ++++++++++++++++++++ .../tuscany/sca/monitor/DefaultMonitorFactory.java | 22 +- .../org/apache/tuscany/sca/monitor/Monitor.java | 5 + .../apache/tuscany/sca/monitor/MonitorFactory.java | 24 + .../tuscany/sca/monitor/impl/MonitorImpl.java | 7 + .../discovery/impl/DomainDiscoveryService.java | 12 +- .../sca/node/impl/CompositeContextImpl.java | 5 + .../tuscany/sca/node/impl/NodeFactoryImpl.java | 66 +- .../org/apache/tuscany/sca/node/impl/NodeImpl.java | 15 +- java/sca/modules/pom.xml | 1 - 34 files changed, 2351 insertions(+), 620 deletions(-) delete mode 100644 java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java create mode 100644 java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/DomainRegistryFactory.java create mode 100644 java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointReferenceBinder.java delete mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointReferenceBuilderImpl.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/DefaultDomainRegistryFactory.java create mode 100644 java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java create mode 100644 java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.AssemblyFactory delete mode 100644 java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder create mode 100644 java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory create mode 100644 java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.EndpointReferenceBinder create mode 100644 java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java create mode 100644 java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java (limited to 'java') diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java deleted file mode 100644 index 0d08c2e5c5..0000000000 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.assembly.builder; - -import org.apache.tuscany.sca.assembly.Composite; -import org.apache.tuscany.sca.assembly.EndpointReference; -import org.apache.tuscany.sca.monitor.Problem; - -/** - * A builder that handles the configuration of endpoint references - * It collects together the logic so that it can be used at build time - * or later on during late binding scenarios - * - * @version $Rev$ $Date$ - */ -public interface EndpointReferenceBuilder { - - /** - * Build an endpoint reference matching reference bindings - * with service bindings. - * - * @param endpointReference - * @param monitor - */ - void buildtimeBuild(Composite composite); - - /** - * Build an endpoint reference matching reference bindings - * with service bindings. - * - * @param endpointReference - * @param monitor - */ - Problem runtimeBuild(EndpointReference endpointReference); - - boolean isOutOfDate(EndpointReference endpointReference); - -} diff --git a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/context/CompositeContext.java b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/context/CompositeContext.java index 942f3bca78..a805985a11 100644 --- a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/context/CompositeContext.java +++ b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/context/CompositeContext.java @@ -21,6 +21,7 @@ package org.apache.tuscany.sca.context; import org.apache.tuscany.sca.assembly.Composite; import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.runtime.EndpointRegistry; @@ -66,6 +67,12 @@ public abstract class CompositeContext { * @param runtimeComponent */ public abstract void bindComponent(RuntimeComponent runtimeComponent); + + /** + * + * @param endpointReference + */ + public abstract void bindEndpointReference(EndpointReference endpointReference); /** * Get the ExtensionPointRegistry for this node diff --git a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/CompositeActivator.java b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/CompositeActivator.java index 3631684a54..f4e18f60cc 100644 --- a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/CompositeActivator.java +++ b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/CompositeActivator.java @@ -31,30 +31,34 @@ import org.apache.tuscany.sca.context.CompositeContext; public interface CompositeActivator { /** * Activate a composite + * @param compositeContext The context of the Node * @param composite */ - void activate(Composite composite) throws ActivationException; + void activate(CompositeContext compositeContext, Composite composite) throws ActivationException; /** * Activate a component reference + * @param compositeContext The context of the Node * @param component * @param ref */ - void start(RuntimeComponent component, RuntimeComponentReference ref); + void start(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentReference ref); /** * Activate a component reference + * @param compositeContext The context of the Node * @param component * @param ref */ - void activate(RuntimeComponent component, RuntimeComponentReference ref); + void activate(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentReference ref); /** * Activate a component reference + * @param compositeContext The context of the Node * @param component * @param ref */ - void activate(RuntimeComponent component, RuntimeComponentService service); + void activate(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentService service); /** * De-activate a component reference diff --git a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/DomainRegistryFactory.java b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/DomainRegistryFactory.java new file mode 100644 index 0000000000..7b71406ac6 --- /dev/null +++ b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/DomainRegistryFactory.java @@ -0,0 +1,46 @@ +/* + * 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.runtime; + +import java.util.Collection; +import java.util.List; + +/** + * + */ +public interface DomainRegistryFactory { + /** + * Get the EndpointRegistry for the given registry URI and domain URI + * @param endpointRegistryURI A URI can be used to connect to the registry, such as vm://localhost + * or multicast://200.0.100.200:50000/... + * @param domainURI The domain URI + * @return + */ + EndpointRegistry getEndpointRegistry(String endpointRegistryURI, String domainURI); + + /** + * Return all active endpoint registries + * @return + */ + Collection getEndpointRegistries(); + void addListener(EndpointListener listener); + void removeListener(EndpointListener listener); + List getListeners(); +} diff --git a/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointReferenceBinder.java b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointReferenceBinder.java new file mode 100644 index 0000000000..78a0e19f10 --- /dev/null +++ b/java/sca/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointReferenceBinder.java @@ -0,0 +1,42 @@ +/* + * 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.runtime; + +import org.apache.tuscany.sca.assembly.EndpointReference; + +/** + * A utility responsible for resolving the endpoint reference against a matching endpoint published + * to the EndpointRegistry + */ +public interface EndpointReferenceBinder { + /** + * @param endpointRegistry + * @param endpointReference + * @return + */ + boolean bind(EndpointRegistry endpointRegistry, EndpointReference endpointReference); + /** + * + * @param endpointRegistry + * @param endpointReference + * @return + */ + boolean isOutOfDate(EndpointRegistry endpointRegistry, EndpointReference endpointReference); +} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java index de9b575926..1c4ded13fc 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java @@ -100,13 +100,13 @@ public class CompositeActivatorImpl implements CompositeActivator { // Composite activation/deactivation - public void activate(Composite composite) throws ActivationException { + public void activate(CompositeContext compositeContext, Composite composite) throws ActivationException { try { if (logger.isLoggable(Level.FINE)) { logger.fine("Activating composite: " + composite.getName()); } for (Component component : composite.getComponents()) { - activateComponent(component); + activateComponent(compositeContext, component); } } catch (Exception e) { throw new ActivationException(e); @@ -128,7 +128,7 @@ public class CompositeActivatorImpl implements CompositeActivator { // Component activation/deactivation - public void activateComponent(Component component) + public void activateComponent(CompositeContext compositeContext, Component component) throws ActivationException { try { if (logger.isLoggable(Level.FINE)) { @@ -137,7 +137,7 @@ public class CompositeActivatorImpl implements CompositeActivator { Implementation implementation = component.getImplementation(); if (implementation instanceof Composite) { - activate((Composite) implementation); + activate(compositeContext, (Composite) implementation); } else if (implementation != null) { addImplementationProvider((RuntimeComponent) component, implementation); @@ -145,13 +145,13 @@ public class CompositeActivatorImpl implements CompositeActivator { } for (ComponentService service : component.getServices()) { - activate((RuntimeComponent) component, - (RuntimeComponentService) service); + activate(compositeContext, + (RuntimeComponent) component, (RuntimeComponentService) service); } for (ComponentReference reference : component.getReferences()) { - activate((RuntimeComponent) component, - (RuntimeComponentReference) reference); + activate(compositeContext, + (RuntimeComponent) component, (RuntimeComponentReference) reference); } } catch (Exception e) { throw new ActivationException(e); @@ -237,7 +237,7 @@ public class CompositeActivatorImpl implements CompositeActivator { // Service activation/deactivation - public void activate(RuntimeComponent component, RuntimeComponentService service) { + public void activate(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentService service) { if (service.getService() == null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Skipping component service not defined in the component type: " + component.getURI() @@ -261,7 +261,7 @@ public class CompositeActivatorImpl implements CompositeActivator { for (Endpoint endpoint : service.getEndpoints()) { addServiceBindingProvider(endpoint, component, service, endpoint.getBinding()); } - addServiceWires(component, service); + addServiceWires(compositeContext, component, service); } public void deactivate(RuntimeComponent component, RuntimeComponentService service) { @@ -313,7 +313,7 @@ public class CompositeActivatorImpl implements CompositeActivator { } } - private void addServiceWires(Component serviceComponent, ComponentService service) { + private void addServiceWires(CompositeContext compositeContext, Component serviceComponent, ComponentService service) { if (!(service instanceof RuntimeComponentService)) { return; } @@ -341,7 +341,7 @@ public class CompositeActivatorImpl implements CompositeActivator { endpointReference.setInterfaceContract(getServiceBindingInterfaceContract(service, endpoint.getBinding())); // create the wire - RuntimeWire wire = new RuntimeWireImpl(extensionPoints, + RuntimeWire wire = new RuntimeWireImpl(compositeContext, false, endpointReference, endpoint, @@ -381,7 +381,7 @@ public class CompositeActivatorImpl implements CompositeActivator { // Reference activation/deactivation - public void activate(RuntimeComponent component, RuntimeComponentReference reference) { + public void activate(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentReference reference) { if (logger.isLoggable(Level.FINE)) { logger.fine("Activating component reference: " + component.getURI() + "#" + reference.getName()); } @@ -641,7 +641,7 @@ public class CompositeActivatorImpl implements CompositeActivator { // Used by component context start // TODO - EPR I don't know why reference wires don't get added until component start - public void start(RuntimeComponent component, RuntimeComponentReference componentReference) { + public void start(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentReference componentReference) { synchronized (componentReference) { if (!(componentReference instanceof RuntimeComponentReference)) { @@ -696,7 +696,7 @@ public class CompositeActivatorImpl implements CompositeActivator { // current composite). Endpoint reference resolution takes place when the wire // is first used (when the chains are created) for (EndpointReference endpointReference : componentReference.getEndpointReferences()){ - addReferenceWire(component, componentReference, endpointReference); + addReferenceWire(compositeContext, component, componentReference, endpointReference); component.getComponentContext().getCompositeContext().getEndpointRegistry().addEndpointReference(endpointReference); } @@ -723,7 +723,7 @@ public class CompositeActivatorImpl implements CompositeActivator { } } - private void addReferenceWire(Component component, ComponentReference reference, EndpointReference endpointReference) { + private void addReferenceWire(CompositeContext compositeContext, Component component, ComponentReference reference, EndpointReference endpointReference) { RuntimeComponentReference runtimeRef = (RuntimeComponentReference)reference; // Use the interface contract of the reference on the component type and if there @@ -789,7 +789,7 @@ public class CompositeActivatorImpl implements CompositeActivator { // create the wire // null endpoint passed in here as the endpoint reference may // not be resolved yet - RuntimeWire wire = new RuntimeWireImpl(extensionPoints, + RuntimeWire wire = new RuntimeWireImpl(compositeContext, true, endpointReference, null, diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointReferenceBuilderImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointReferenceBuilderImpl.java deleted file mode 100644 index b37699580e..0000000000 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointReferenceBuilderImpl.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * 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.core.assembly.impl; - -import java.util.List; - -import org.apache.tuscany.sca.assembly.AssemblyFactory; -import org.apache.tuscany.sca.assembly.Composite; -import org.apache.tuscany.sca.assembly.Endpoint; -import org.apache.tuscany.sca.assembly.EndpointReference; -import org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder; -import org.apache.tuscany.sca.core.ExtensionPointRegistry; -import org.apache.tuscany.sca.core.FactoryExtensionPoint; -import org.apache.tuscany.sca.core.UtilityExtensionPoint; -import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; -import org.apache.tuscany.sca.monitor.Monitor; -import org.apache.tuscany.sca.monitor.MonitorFactory; -import org.apache.tuscany.sca.monitor.Problem; -import org.apache.tuscany.sca.runtime.EndpointRegistry; - -/** - * An builder that takes endpoint references and resolves them. It either finds local - * service endpoints if they are available or asks the domain. The main function here - * is to perform binding and policy matching. - * This is a separate builder in case it is required by undresolved endpoints - * once the runtime has started. - * - * @version $Rev$ $Date$ - */ -public class EndpointReferenceBuilderImpl implements EndpointReferenceBuilder { - - protected ExtensionPointRegistry extensionPoints; - protected AssemblyFactory assemblyFactory; - protected InterfaceContractMapper interfaceContractMapper; - protected EndpointRegistry endpointRegistry; - private Monitor monitor; - - - public EndpointReferenceBuilderImpl(ExtensionPointRegistry extensionPoints) { - this.extensionPoints = extensionPoints; - - FactoryExtensionPoint factories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); - this.assemblyFactory = factories.getFactory(AssemblyFactory.class); - - UtilityExtensionPoint utils = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); - this.interfaceContractMapper = utils.getUtility(InterfaceContractMapper.class); - this.endpointRegistry = utils.getUtility(EndpointRegistry.class); - MonitorFactory monitorFactory = utils.getUtility(MonitorFactory.class); - monitor = monitorFactory.createMonitor(); - } - - /** - * Build a composite - * - * @param endpoint - * @param monitor - */ - public void buildtimeBuild(Composite composite) { - // TODO - ready for reorganization of the builders - // build all the endpoint references in a composite - // that it is possible to build in order to get any - // errors out as early as possible. Any that can't - // be built now must wait until runtime - } - - /** - * Build a single endpoint reference - * - * @param endpoint - * @param monitor - */ - public Problem runtimeBuild(EndpointReference endpointReference) { - - Problem problem = null; - - if ( endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED || - endpointReference.getStatus() == EndpointReference.RESOLVED_BINDING ) { - // The endpoint reference is already resolved to either - // a service endpoint local to this composite or it has - // a remote binding - - // still need to check that the callback endpoint is set correctly - if (hasCallback(endpointReference) && - endpointReference.getCallbackEndpoint() != null && - endpointReference.getCallbackEndpoint().isUnresolved() == true ){ - problem = selectCallbackEndpoint(endpointReference, - endpointReference.getReference().getCallbackService().getEndpoints()); - } - } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_READY_FOR_MATCHING ){ - // The endpoint reference is already resolved to either - // a service endpoint but no binding was specified in the - // target URL and/or the policies have yet to be matched. - - problem = selectForwardEndpoint(endpointReference, - endpointReference.getTargetEndpoint().getService().getEndpoints()); - - if (problem == null && hasCallback(endpointReference)){ - problem = selectCallbackEndpoint(endpointReference, - endpointReference.getReference().getCallbackService().getEndpoints()); - } - - } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_NOT_FOUND || - endpointReference.getStatus() == EndpointReference.NOT_CONFIGURED){ - // The service is in a remote composite somewhere else in the domain - - // find the service in the endpoint registry - List endpoints = endpointRegistry.findEndpoint(endpointReference); - - if (endpoints.size() == 0) { - problem = monitor.createProblem(this.getClass().getName(), - "endpoint-validation-messages", - Problem.Severity.ERROR, - this, - "NoEndpointsFound", - endpointReference.toString()); - } - - problem = selectForwardEndpoint(endpointReference, - endpoints); - - if (problem == null && hasCallback(endpointReference)){ - problem = selectCallbackEndpoint(endpointReference, - endpointReference.getReference().getCallbackService().getEndpoints()); - } - } - - if (problem != null){ - return problem; - } - - if (endpointReference.getStatus() != EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED && - endpointReference.getStatus() != EndpointReference.RESOLVED_BINDING){ - problem = monitor.createProblem(this.getClass().getName(), - "endpoint-validation-messages", - Problem.Severity.ERROR, - this, - "EndpointReferenceCantBeMatched", - endpointReference.toString()); - } - - return problem; - } - - private Problem selectForwardEndpoint(EndpointReference endpointReference, List endpoints) { - - Endpoint matchedEndpoint = null; - - if (endpointReference.getReference().getName().startsWith("$self$.")){ - // just select the first one and don't do any policy matching - matchedEndpoint = endpoints.get(0); - } else { - // find the first endpoint that matches this endpoint reference - for (Endpoint endpoint : endpoints){ - if (haveMatchingPolicy(endpointReference, endpoint)){ - matchedEndpoint = endpoint; - } - } - } - - if (matchedEndpoint == null){ - return null; - } - - endpointReference.setTargetEndpoint(matchedEndpoint); - endpointReference.setBinding(endpointReference.getTargetEndpoint().getBinding()); - endpointReference.setStatus(EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED); - endpointReference.setUnresolved(false); - - return null; - } - - private boolean hasCallback(EndpointReference endpointReference){ - if (endpointReference.getReference().getInterfaceContract() == null || - endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null || - endpointReference.getReference().getName().startsWith("$self$.")){ - return false; - } else { - return true; - } - } - - private Problem selectCallbackEndpoint(EndpointReference endpointReference, List endpoints) { - - Problem problem = null; - - // find the first callback endpoint that matches a callback endpoint reference - // at the service - Endpoint matchedEndpoint = null; - match: - for ( EndpointReference callbackEndpointReference : endpointReference.getTargetEndpoint().getCallbackEndpointReferences()){ - for (Endpoint endpoint : endpoints){ - if (haveMatchingPolicy(callbackEndpointReference, endpoint)){ - matchedEndpoint = endpoint; - break match; - } - } - } - - if (matchedEndpoint == null){ - return null; - } - - endpointReference.setCallbackEndpoint(matchedEndpoint); - - return problem; - } - - // FIXME: [rfeng] This implementation is wrong. It is the responsibility of the policy language - // to compare the reference and service side setting to determine if they are compatible. Some of - // policies apply to the reference side only, some of the policies apply to the service side only, - // while others apply to both sides. Even for those policies that apply to both side, they can be - // independent or related. - private boolean haveMatchingPolicy(EndpointReference endpointReference, Endpoint endpoint){ - - /* - // if no policy sets or intents are present then they match - if ((endpointReference.getRequiredIntents().size() == 0) && - (endpoint.getRequiredIntents().size() == 0) && - (endpointReference.getPolicySets().size() == 0) && - (endpoint.getPolicySets().size() == 0)) { - return true; - } - - // if there are different numbers of intents - // then they don't match - if (endpointReference.getRequiredIntents().size() != - endpoint.getRequiredIntents().size()) { - return false; - } - - // if there are different numbers of policy sets - // then they don't match - if (endpointReference.getPolicySets().size() != - endpoint.getPolicySets().size()) { - return false; - } - - // check intents for compatibility - for(Intent intentEPR : endpointReference.getRequiredIntents()){ - boolean matched = false; - for (Intent intentEP : endpoint.getRequiredIntents()){ - if (intentEPR.getName().equals(intentEP.getName())){ - matched = true; - break; - } - } - if (matched == false){ - return false; - } - } - - // check policy sets for compatibility. The list of policy sets - // may be a subset of the list of intents as some of the intents - // may be directly provided. We can't just rely on intent compatibility - // as different policy sets might have been attached at each end to - // satisfy the listed intents - - // if all of the policy sets on the endpoint reference match a - // policy set on the endpoint then they match - for(PolicySet policySetEPR : endpointReference.getPolicySets()){ - boolean matched = false; - for (PolicySet policySetEP : endpoint.getPolicySets()){ - // find if there is a policy set with the same name - if (policySetEPR.getName().equals(policySetEP.getName())){ - matched = true; - break; - } - // find if the policies inside the policy set match the - // policies inside a policy set on the endpoint - - // TODO - need a policy specific matcher to do this - // so need a new extension point - - } - - if (matched == false){ - return false; - } - } - */ - - return true; - } - - public boolean isOutOfDate(EndpointReference endpointReference) { - Endpoint te = endpointReference.getTargetEndpoint(); - if (!te.isUnresolved() && te.getURI()!= null) { - List endpoints = endpointRegistry.findEndpoint(endpointReference); - return ! endpoints.contains(endpointReference.getTargetEndpoint()); - } - return false; - } - -} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java index 1317c3fc8f..2ad61963e0 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java @@ -20,9 +20,8 @@ package org.apache.tuscany.sca.core.assembly.impl; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Logger; import org.apache.tuscany.sca.assembly.Endpoint; @@ -38,25 +37,23 @@ import org.apache.tuscany.sca.runtime.EndpointRegistry; public class EndpointRegistryImpl implements EndpointRegistry, LifeCycleListener { private final Logger logger = Logger.getLogger(EndpointRegistryImpl.class.getName()); - private MappedList endpoints = new MappedList(); - private MappedList endpointreferences = - new MappedList(); + private List endpoints = new ArrayList(); + private List endpointreferences = new ArrayList(); + private List listeners = new ArrayList(); - private List listeners = new CopyOnWriteArrayList(); - - public EndpointRegistryImpl(ExtensionPointRegistry extensionPoints) { + public EndpointRegistryImpl(ExtensionPointRegistry extensionPoints, String endpointRegistryURI, String domainURI) { } - public void addEndpoint(Endpoint endpoint) { - endpoints.putValue(this, endpoint); + public synchronized void addEndpoint(Endpoint endpoint) { + endpoints.add(endpoint); for (EndpointListener listener : listeners) { listener.endpointAdded(endpoint); } logger.info("Add endpoint - " + endpoint.toString()); } - public void addEndpointReference(EndpointReference endpointReference) { - endpointreferences.putValue(this, endpointReference); + public synchronized void addEndpointReference(EndpointReference endpointReference) { + endpointreferences.add(endpointReference); logger.fine("Add endpoint reference - " + endpointReference.toString()); } @@ -104,153 +101,108 @@ public class EndpointRegistryImpl implements EndpointRegistry, LifeCycleListener return true; } - public List findEndpoint(EndpointReference endpointReference) { + public synchronized List findEndpoint(EndpointReference endpointReference) { List foundEndpoints = new ArrayList(); logger.fine("Find endpoint for reference - " + endpointReference.toString()); if (endpointReference.getReference() != null) { Endpoint targetEndpoint = endpointReference.getTargetEndpoint(); - for (List collection : endpoints.values()) { - for (Endpoint endpoint : collection) { - // TODO: implement more complete matching - if (matches(targetEndpoint.getURI(), endpoint.getURI())) { - foundEndpoints.add(endpoint); - logger.fine("Found endpoint with matching service - " + endpoint); - } - // else the service name doesn't match + for (Endpoint endpoint : endpoints) { + // TODO: implement more complete matching + if (matches(targetEndpoint.getURI(), endpoint.getURI())) { + foundEndpoints.add(endpoint); + logger.fine("Found endpoint with matching service - " + endpoint); } + // else the service name doesn't match } } return foundEndpoints; } - public List findEndpointReference(Endpoint endpoint) { + public synchronized List findEndpointReference(Endpoint endpoint) { return null; } - public void removeEndpoint(Endpoint endpoint) { - endpoints.removeValue(this, endpoint); + public synchronized void removeEndpoint(Endpoint endpoint) { + endpoints.remove(endpoint); + endpointRemoved(endpoint); + } + + private void endpointRemoved(Endpoint endpoint) { for (EndpointListener listener : listeners) { listener.endpointRemoved(endpoint); } logger.info("Remove endpoint - " + endpoint.toString()); } - public void removeEndpointReference(EndpointReference endpointReference) { - endpointreferences.removeValue(this, endpointReference); + public synchronized void removeEndpointReference(EndpointReference endpointReference) { + endpointreferences.remove(endpointReference); logger.fine("Remove endpoint reference - " + endpointReference.toString()); } - public List getEndpointRefereneces() { - return endpointreferences.getAllValues(); + public synchronized List getEndpointRefereneces() { + return endpointreferences; } - public List getEndpoints() { - return endpoints.getAllValues(); + public synchronized List getEndpoints() { + return endpoints; } - public void addListener(EndpointListener listener) { + public synchronized void addListener(EndpointListener listener) { listeners.add(listener); } - public List getListeners() { + public synchronized List getListeners() { return listeners; } - public void removeListener(EndpointListener listener) { + public synchronized void removeListener(EndpointListener listener) { listeners.remove(listener); } - public Endpoint getEndpoint(String uri) { - for (List collection : endpoints.values()) { - for (Endpoint ep : collection) { - String epURI = - ep.getComponent().getURI() + "#" + ep.getService().getName() + "/" + ep.getBinding().getName(); + public synchronized Endpoint getEndpoint(String uri) { + for (Endpoint ep : endpoints) { + String epURI = + ep.getComponent().getURI() + "#" + ep.getService().getName() + "/" + ep.getBinding().getName(); + if (epURI.equals(uri)) { + return ep; + } + if (ep.getBinding().getName() == null || ep.getBinding().getName().equals(ep.getService().getName())) { + epURI = ep.getComponent().getURI() + "#" + ep.getService().getName(); if (epURI.equals(uri)) { return ep; } - if (ep.getBinding().getName() == null || ep.getBinding().getName().equals(ep.getService().getName())) { - epURI = ep.getComponent().getURI() + "#" + ep.getService().getName(); - if (epURI.equals(uri)) { - return ep; - } - } } } return null; } - public void updateEndpoint(String uri, Endpoint endpoint) { + public synchronized void updateEndpoint(String uri, Endpoint endpoint) { Endpoint oldEndpoint = getEndpoint(uri); if (oldEndpoint == null) { throw new IllegalArgumentException("Endpoint is not found: " + uri); } - endpoints.removeValue(this, oldEndpoint); - endpoints.putValue(this, endpoint); + endpoints.remove(oldEndpoint); + endpoints.add(endpoint); for (EndpointListener listener : listeners) { listener.endpointUpdated(oldEndpoint, endpoint); } } - public void start() { + public synchronized void start() { } - public void stop() { - List localEndpoints = endpoints.remove(this); - if (localEndpoints != null) { - for (Endpoint endpoint : localEndpoints) { - removeEndpoint(endpoint); - } - } - List localEndpointReferences = endpointreferences.remove(this); - if (localEndpointReferences != null) { - for (EndpointReference endpointReference : localEndpointReferences) { - removeEndpointReference(endpointReference); - } + public synchronized void stop() { + for (Iterator i = endpoints.iterator(); i.hasNext();) { + Endpoint ep = i.next(); + i.remove(); + endpointRemoved(ep); } + endpointreferences.clear(); listeners.clear(); } - private static class MappedList extends ConcurrentHashMap> { - private static final long serialVersionUID = -8926174610229029369L; - - public boolean putValue(K key, V value) { - List collection = get(key); - if (collection == null) { - collection = new ArrayList(); - put(key, collection); - } - return collection.add(value); - } - - public boolean putValue(K key, List value) { - List collection = get(key); - if (collection == null) { - collection = new ArrayList(); - put(key, collection); - } - return collection.addAll(value); - } - - public boolean removeValue(K key, V value) { - List collection = get(key); - if (collection == null) { - return false; - } - return collection.remove(value); - } - - public List getAllValues() { - List values = new ArrayList(); - for (List collection : values()) { - values.addAll(collection); - } - return values; - } - - } - } diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java index 4474c26deb..62b71c47d1 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java @@ -35,7 +35,7 @@ import org.apache.tuscany.sca.assembly.Contract; import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.assembly.EndpointReference; import org.apache.tuscany.sca.assembly.Service; -import org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder; +import org.apache.tuscany.sca.context.CompositeContext; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.core.UtilityExtensionPoint; @@ -52,7 +52,6 @@ import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.invocation.Phase; -import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.provider.BindingProviderFactory; import org.apache.tuscany.sca.provider.ImplementationProvider; import org.apache.tuscany.sca.provider.PolicyProvider; @@ -63,6 +62,7 @@ import org.apache.tuscany.sca.provider.ReferenceBindingProvider; import org.apache.tuscany.sca.provider.ReferenceBindingProviderRRB; import org.apache.tuscany.sca.provider.ServiceBindingProvider; import org.apache.tuscany.sca.provider.ServiceBindingProviderRRB; +import org.apache.tuscany.sca.runtime.EndpointReferenceBinder; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentReference; import org.apache.tuscany.sca.runtime.RuntimeComponentService; @@ -78,7 +78,8 @@ import org.oasisopen.sca.ServiceRuntimeException; */ public class RuntimeWireImpl implements RuntimeWire { - ExtensionPointRegistry extensionPoints; + private CompositeContext compositeContext; + private ExtensionPointRegistry extensionPoints; private Boolean isReferenceWire = false; private EndpointReference endpointReference; @@ -100,7 +101,7 @@ public class RuntimeWireImpl implements RuntimeWire { private List chains; private InvocationChain bindingInvocationChain; - private EndpointReferenceBuilder endpointReferenceBuilder; + private EndpointReferenceBinder eprBinder; private final ProviderFactoryExtensionPoint providerFactories; /** @@ -112,7 +113,7 @@ public class RuntimeWireImpl implements RuntimeWire { * @param messageFactory * @param conversationManager */ - public RuntimeWireImpl(ExtensionPointRegistry extensionPoints, + public RuntimeWireImpl(CompositeContext compositeContext, boolean isReferenceWire, EndpointReference endpointReference, Endpoint endpoint, @@ -121,7 +122,8 @@ public class RuntimeWireImpl implements RuntimeWire { RuntimeWireProcessor wireProcessor, MessageFactory messageFactory) { super(); - this.extensionPoints = extensionPoints; + this.compositeContext = compositeContext; + this.extensionPoints = compositeContext.getExtensionPointRegistry(); this.isReferenceWire = isReferenceWire; this.endpointReference = endpointReference; this.endpoint = endpoint; @@ -132,16 +134,17 @@ public class RuntimeWireImpl implements RuntimeWire { this.invoker = new RuntimeWireInvoker(this.messageFactory, this); UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); - this.endpointReferenceBuilder = utilities.getUtility(EndpointReferenceBuilder.class); + this.eprBinder = utilities.getUtility(EndpointReferenceBinder.class); this.providerFactories = extensionPoints.getExtensionPoint(ProviderFactoryExtensionPoint.class); } - public RuntimeWireImpl(ExtensionPointRegistry extensionPoints, + public RuntimeWireImpl(CompositeContext compositeContext, boolean isReferenceWire, EndpointReference endpointReference, Endpoint endpoint) { super(); - this.extensionPoints = extensionPoints; + this.compositeContext = compositeContext; + this.extensionPoints = compositeContext.getExtensionPointRegistry(); this.isReferenceWire = isReferenceWire; this.endpointReference = endpointReference; this.endpoint = endpoint; @@ -154,9 +157,10 @@ public class RuntimeWireImpl implements RuntimeWire { this.messageFactory = factories.getFactory(MessageFactory.class); this.invoker = new RuntimeWireInvoker(this.messageFactory, this); - this.endpointReferenceBuilder = utilities.getUtility(EndpointReferenceBuilder.class); + this.eprBinder = utilities.getUtility(EndpointReferenceBinder.class); this.providerFactories = extensionPoints.getExtensionPoint(ProviderFactoryExtensionPoint.class); } + public synchronized List getInvocationChains() { if (chains == null) { initInvocationChains(); @@ -331,10 +335,10 @@ public class RuntimeWireImpl implements RuntimeWire { * is first used */ private void resolveEndpointReference(){ - Problem problem = endpointReferenceBuilder.runtimeBuild(endpointReference); + boolean ok = eprBinder.bind(compositeContext.getEndpointRegistry(), endpointReference); - if (problem != null){ - throw new SCARuntimeException(problem.toString()); + if (!ok) { + throw new SCARuntimeException("Unable to bind " + endpointReference); } // set the endpoint based on the resolved endpoint @@ -774,6 +778,6 @@ public class RuntimeWireImpl implements RuntimeWire { } public boolean isOutOfDate() { - return endpointReferenceBuilder.isOutOfDate(getEndpointReference()); + return eprBinder.isOutOfDate(compositeContext.getEndpointRegistry(), getEndpointReference()); } } diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java index b88c395f31..d1bec6285c 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java @@ -34,7 +34,6 @@ import org.apache.tuscany.sca.assembly.Multiplicity; import org.apache.tuscany.sca.assembly.OptimizableBinding; import org.apache.tuscany.sca.assembly.Reference; import org.apache.tuscany.sca.assembly.Service; -import org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder; import org.apache.tuscany.sca.context.CompositeContext; import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint; import org.apache.tuscany.sca.context.PropertyValueFactory; @@ -52,8 +51,8 @@ import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.monitor.MonitorFactory; -import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.runtime.CompositeActivator; +import org.apache.tuscany.sca.runtime.EndpointReferenceBinder; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentContext; import org.apache.tuscany.sca.runtime.RuntimeComponentReference; @@ -78,7 +77,7 @@ public class ComponentContextImpl implements RuntimeComponentContext { private final AssemblyFactory assemblyFactory; private final JavaInterfaceFactory javaInterfaceFactory; private final PropertyValueFactory propertyFactory; - private final EndpointReferenceBuilder endpointReferenceBuilder; + private final EndpointReferenceBinder eprBinder; private final Monitor monitor; public ComponentContextImpl(ExtensionPointRegistry registry, CompositeContext compositeContext, RuntimeComponent component) { @@ -97,7 +96,7 @@ public class ComponentContextImpl implements RuntimeComponentContext { this.proxyFactory = new ExtensibleProxyFactory(registry.getExtensionPoint(ProxyFactoryExtensionPoint.class)); this.propertyFactory = factories.getFactory(PropertyValueFactory.class); - this.endpointReferenceBuilder = utilities.getUtility(EndpointReferenceBuilder.class); + this.eprBinder = utilities.getUtility(EndpointReferenceBinder.class); MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); this.monitor = monitorFactory.createMonitor(); @@ -394,10 +393,10 @@ public class ComponentContextImpl implements RuntimeComponentContext { componentReference.getEndpointReferences().add(endpointReference); // do binding matching - Problem problem = endpointReferenceBuilder.runtimeBuild(endpointReference); + boolean ok = eprBinder.bind(compositeContext.getEndpointRegistry(), endpointReference); - if (problem != null){ - throw new SCARuntimeException(problem.toString()); + if (!ok) { + throw new SCARuntimeException("Unable to bind " + endpointReference); } return componentReference; @@ -441,7 +440,7 @@ public class ComponentContextImpl implements RuntimeComponentContext { * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#start(org.apache.tuscany.sca.runtime.RuntimeComponentReference) */ public void start(RuntimeComponentReference reference) { - compositeActivator.start(component, reference); + compositeActivator.start(compositeContext, component, reference); } diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/DefaultDomainRegistryFactory.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/DefaultDomainRegistryFactory.java new file mode 100644 index 0000000000..d80e2b5490 --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/DefaultDomainRegistryFactory.java @@ -0,0 +1,157 @@ +/* + * 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.core.runtime; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.LifeCycleListener; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.runtime.DomainRegistryFactory; +import org.apache.tuscany.sca.runtime.EndpointListener; +import org.apache.tuscany.sca.runtime.EndpointRegistry; + +/** + * The utility responsible for finding the endpoint regstry by the scheme and creating instances for the + * given domain + */ +public class DefaultDomainRegistryFactory implements DomainRegistryFactory, LifeCycleListener { + private ExtensionPointRegistry extensionRegistry; + private Map declarations = new HashMap(); + private Map endpointRegistries = new ConcurrentHashMap(); + private List listeners = new ArrayList(); + + /** + * @param extensionRegistry + */ + public DefaultDomainRegistryFactory(ExtensionPointRegistry extensionRegistry) { + super(); + this.extensionRegistry = extensionRegistry; + } + + public void start() { + Collection sds = null; + try { + sds = ServiceDiscovery.getInstance().getServiceDeclarations(EndpointRegistry.class); + } catch (IOException e) { + throw new IllegalStateException(e); + } + for (ServiceDeclaration sd : sds) { + String scheme = sd.getAttributes().get("scheme"); + if (scheme != null) { + scheme = scheme.toLowerCase(); + } + declarations.put(scheme, sd); + } + } + + public synchronized EndpointRegistry getEndpointRegistry(String endpointRegistryURI, String domainURI) { + if (endpointRegistryURI == null) { + endpointRegistryURI = "vm://localhost"; + } + + String key = endpointRegistryURI + "," + domainURI; + + EndpointRegistry endpointRegistry = endpointRegistries.get(key); + if (endpointRegistry != null) { + return endpointRegistry; + } + + URI uri = URI.create(endpointRegistryURI); + String scheme = uri.getScheme(); + if (scheme != null) { + scheme = scheme.toLowerCase(); + } + + ServiceDeclaration sd = declarations.get(scheme); + + try { + Class implClass = sd.loadClass(); + Constructor constructor = null; + try { + constructor = implClass.getConstructor(ExtensionPointRegistry.class, String.class, String.class); + endpointRegistry = + (EndpointRegistry)constructor.newInstance(extensionRegistry, endpointRegistryURI, domainURI); + } catch (NoSuchMethodException e) { + constructor = + implClass.getConstructor(ExtensionPointRegistry.class, Map.class, String.class, String.class); + endpointRegistry = + (EndpointRegistry)constructor.newInstance(extensionRegistry, + sd.getAttributes(), + endpointRegistryURI, + domainURI); + } + } catch (Exception e) { + throw new IllegalStateException(e); + } + + if (endpointRegistry instanceof LifeCycleListener) { + ((LifeCycleListener)endpointRegistry).start(); + } + + for (EndpointListener listener : listeners) { + endpointRegistry.addListener(listener); + } + endpointRegistries.put(key, endpointRegistry); + return endpointRegistry; + } + + public void stop() { + declarations.clear(); + for (EndpointRegistry endpointRegistry : endpointRegistries.values()) { + if (endpointRegistry instanceof LifeCycleListener) { + ((LifeCycleListener)endpointRegistry).stop(); + } + } + endpointRegistries.clear(); + listeners.clear(); + } + + public synchronized Collection getEndpointRegistries() { + return new ArrayList(endpointRegistries.values()); + } + + public synchronized void addListener(EndpointListener listener) { + listeners.add(listener); + for(EndpointRegistry registry: endpointRegistries.values()) { + registry.addListener(listener); + } + } + + public synchronized List getListeners() { + return listeners; + } + + public synchronized void removeListener(EndpointListener listener) { + listeners.remove(listener); + for(EndpointRegistry registry: endpointRegistries.values()) { + registry.removeListener(listener); + } + } +} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java new file mode 100644 index 0000000000..bab83bad2d --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java @@ -0,0 +1,299 @@ +/* + * 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.core.runtime.impl; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.runtime.EndpointReferenceBinder; +import org.apache.tuscany.sca.runtime.EndpointRegistry; + +/** + * An builder that takes endpoint references and resolves them. It either finds local + * service endpoints if they are available or asks the domain. The main function here + * is to perform binding and policy matching. + * This is a separate builder in case it is required by undresolved endpoints + * once the runtime has started. + * + * @version $Rev$ $Date$ + */ +public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { + + protected ExtensionPointRegistry extensionPoints; + protected AssemblyFactory assemblyFactory; + protected InterfaceContractMapper interfaceContractMapper; + private Monitor monitor; + + + public EndpointReferenceBinderImpl(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + + FactoryExtensionPoint factories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + this.assemblyFactory = factories.getFactory(AssemblyFactory.class); + + UtilityExtensionPoint utils = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + this.interfaceContractMapper = utils.getUtility(InterfaceContractMapper.class); + MonitorFactory monitorFactory = utils.getUtility(MonitorFactory.class); + monitor = monitorFactory.createMonitor(); + } + + + + /** + * Build a single endpoint reference + * + * @param endpoint + * @param monitor + */ + public boolean bind(EndpointRegistry endpointRegistry, EndpointReference endpointReference) { + Problem problem = null; + if ( endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED || + endpointReference.getStatus() == EndpointReference.RESOLVED_BINDING ) { + // The endpoint reference is already resolved to either + // a service endpoint local to this composite or it has + // a remote binding + + // still need to check that the callback endpoint is set correctly + if (hasCallback(endpointReference) && + endpointReference.getCallbackEndpoint() != null && + endpointReference.getCallbackEndpoint().isUnresolved() == true ){ + problem = selectCallbackEndpoint(endpointReference, + endpointReference.getReference().getCallbackService().getEndpoints()); + } + } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_READY_FOR_MATCHING ){ + // The endpoint reference is already resolved to either + // a service endpoint but no binding was specified in the + // target URL and/or the policies have yet to be matched. + + problem = selectForwardEndpoint(endpointReference, + endpointReference.getTargetEndpoint().getService().getEndpoints()); + + if (problem == null && hasCallback(endpointReference)){ + problem = selectCallbackEndpoint(endpointReference, + endpointReference.getReference().getCallbackService().getEndpoints()); + } + + } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_NOT_FOUND || + endpointReference.getStatus() == EndpointReference.NOT_CONFIGURED){ + // The service is in a remote composite somewhere else in the domain + + // find the service in the endpoint registry + List endpoints = endpointRegistry.findEndpoint(endpointReference); + + if (endpoints.size() == 0) { + problem = monitor.createProblem(this.getClass().getName(), + "endpoint-validation-messages", + Problem.Severity.ERROR, + this, + "NoEndpointsFound", + endpointReference.toString()); + } + + problem = selectForwardEndpoint(endpointReference, + endpoints); + + if (problem == null && hasCallback(endpointReference)){ + problem = selectCallbackEndpoint(endpointReference, + endpointReference.getReference().getCallbackService().getEndpoints()); + } + } + + if (problem != null){ + monitor.problem(problem); + return false; + } + + if (endpointReference.getStatus() != EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED && + endpointReference.getStatus() != EndpointReference.RESOLVED_BINDING){ + problem = monitor.createProblem(this.getClass().getName(), + "endpoint-validation-messages", + Problem.Severity.ERROR, + this, + "EndpointReferenceCantBeMatched", + endpointReference.toString()); + monitor.problem(problem); + return false; + } + + return true; + + } + + private Problem selectForwardEndpoint(EndpointReference endpointReference, List endpoints) { + + Endpoint matchedEndpoint = null; + + if (endpointReference.getReference().getName().startsWith("$self$.")){ + // just select the first one and don't do any policy matching + matchedEndpoint = endpoints.get(0); + } else { + // find the first endpoint that matches this endpoint reference + for (Endpoint endpoint : endpoints){ + if (haveMatchingPolicy(endpointReference, endpoint)){ + matchedEndpoint = endpoint; + break; + } + } + } + + if (matchedEndpoint == null){ + return null; + } + + endpointReference.setTargetEndpoint(matchedEndpoint); + endpointReference.setBinding(endpointReference.getTargetEndpoint().getBinding()); + endpointReference.setStatus(EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED); + endpointReference.setUnresolved(false); + + return null; + } + + private boolean hasCallback(EndpointReference endpointReference){ + if (endpointReference.getReference().getInterfaceContract() == null || + endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null || + endpointReference.getReference().getName().startsWith("$self$.")){ + return false; + } else { + return true; + } + } + + private Problem selectCallbackEndpoint(EndpointReference endpointReference, List endpoints) { + + Problem problem = null; + + // find the first callback endpoint that matches a callback endpoint reference + // at the service + Endpoint matchedEndpoint = null; + match: + for ( EndpointReference callbackEndpointReference : endpointReference.getTargetEndpoint().getCallbackEndpointReferences()){ + for (Endpoint endpoint : endpoints){ + if (haveMatchingPolicy(callbackEndpointReference, endpoint)){ + matchedEndpoint = endpoint; + break match; + } + } + } + + if (matchedEndpoint == null){ + return null; + } + + endpointReference.setCallbackEndpoint(matchedEndpoint); + + return problem; + } + + // FIXME: [rfeng] This implementation is wrong. It is the responsibility of the policy language + // to compare the reference and service side setting to determine if they are compatible. Some of + // policies apply to the reference side only, some of the policies apply to the service side only, + // while others apply to both sides. Even for those policies that apply to both side, they can be + // independent or related. + private boolean haveMatchingPolicy(EndpointReference endpointReference, Endpoint endpoint){ + + /* + // if no policy sets or intents are present then they match + if ((endpointReference.getRequiredIntents().size() == 0) && + (endpoint.getRequiredIntents().size() == 0) && + (endpointReference.getPolicySets().size() == 0) && + (endpoint.getPolicySets().size() == 0)) { + return true; + } + + // if there are different numbers of intents + // then they don't match + if (endpointReference.getRequiredIntents().size() != + endpoint.getRequiredIntents().size()) { + return false; + } + + // if there are different numbers of policy sets + // then they don't match + if (endpointReference.getPolicySets().size() != + endpoint.getPolicySets().size()) { + return false; + } + + // check intents for compatibility + for(Intent intentEPR : endpointReference.getRequiredIntents()){ + boolean matched = false; + for (Intent intentEP : endpoint.getRequiredIntents()){ + if (intentEPR.getName().equals(intentEP.getName())){ + matched = true; + break; + } + } + if (matched == false){ + return false; + } + } + + // check policy sets for compatibility. The list of policy sets + // may be a subset of the list of intents as some of the intents + // may be directly provided. We can't just rely on intent compatibility + // as different policy sets might have been attached at each end to + // satisfy the listed intents + + // if all of the policy sets on the endpoint reference match a + // policy set on the endpoint then they match + for(PolicySet policySetEPR : endpointReference.getPolicySets()){ + boolean matched = false; + for (PolicySet policySetEP : endpoint.getPolicySets()){ + // find if there is a policy set with the same name + if (policySetEPR.getName().equals(policySetEP.getName())){ + matched = true; + break; + } + // find if the policies inside the policy set match the + // policies inside a policy set on the endpoint + + // TODO - need a policy specific matcher to do this + // so need a new extension point + + } + + if (matched == false){ + return false; + } + } + */ + + return true; + } + + public boolean isOutOfDate(EndpointRegistry endpointRegistry, EndpointReference endpointReference) { + Endpoint te = endpointReference.getTargetEndpoint(); + if (!te.isUnresolved() && te.getURI()!= null) { + List endpoints = endpointRegistry.findEndpoint(endpointReference); + return ! endpoints.contains(endpointReference.getTargetEndpoint()); + } + return false; + } + +} diff --git a/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.AssemblyFactory b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.AssemblyFactory new file mode 100644 index 0000000000..d30dc5b7d7 --- /dev/null +++ b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.AssemblyFactory @@ -0,0 +1,18 @@ +# 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. +# Set the ranking to be greater than the DefaultAssemblyFactory +org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory;ranking=100 \ No newline at end of file diff --git a/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder deleted file mode 100644 index 8f721db536..0000000000 --- a/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder +++ /dev/null @@ -1,18 +0,0 @@ -# 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. - -org.apache.tuscany.sca.core.assembly.impl.EndpointReferenceBuilderImpl \ No newline at end of file diff --git a/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory new file mode 100644 index 0000000000..23c8ba044a --- /dev/null +++ b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory @@ -0,0 +1,17 @@ +# 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. +org.apache.tuscany.sca.core.runtime.DefaultDomainRegistryFactory diff --git a/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.EndpointReferenceBinder b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.EndpointReferenceBinder new file mode 100644 index 0000000000..9315a855b2 --- /dev/null +++ b/java/sca/modules/core/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.EndpointReferenceBinder @@ -0,0 +1,17 @@ +# 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. +org.apache.tuscany.sca.core.runtime.impl.EndpointReferenceBinderImpl diff --git a/java/sca/modules/domain-node/META-INF/MANIFEST.MF b/java/sca/modules/domain-node/META-INF/MANIFEST.MF index 89432db62f..abec7ae294 100644 --- a/java/sca/modules/domain-node/META-INF/MANIFEST.MF +++ b/java/sca/modules/domain-node/META-INF/MANIFEST.MF @@ -11,6 +11,7 @@ Bundle-Description: Apache Tuscany SCA Domain Node Import-Package: org.apache.tuscany.sca.management;version="2.0.0", org.apache.tuscany.sca.node;version="2.0.0", + org.apache.tuscany.sca.node.configuration;version="2.0.0", org.apache.tuscany.sca.node.impl;version="2.0.0" Bundle-SymbolicName: org.apache.tuscany.sca.domain.node Bundle-DocURL: http://www.apache.org/ diff --git a/java/sca/modules/domain-node/pom.xml b/java/sca/modules/domain-node/pom.xml index 0a2d3c274c..6ff228d4fd 100644 --- a/java/sca/modules/domain-node/pom.xml +++ b/java/sca/modules/domain-node/pom.xml @@ -58,12 +58,6 @@ 2.0-SNAPSHOT - - org.apache.tuscany.sca - tuscany-endpoint-wrapper - 2.0-SNAPSHOT - - diff --git a/java/sca/modules/domain-node/src/main/java/org/apache/tuscany/sca/domain/node/DomainNode.java b/java/sca/modules/domain-node/src/main/java/org/apache/tuscany/sca/domain/node/DomainNode.java index 761e9d25a7..1259870c37 100644 --- a/java/sca/modules/domain-node/src/main/java/org/apache/tuscany/sca/domain/node/DomainNode.java +++ b/java/sca/modules/domain-node/src/main/java/org/apache/tuscany/sca/domain/node/DomainNode.java @@ -24,10 +24,9 @@ import java.util.HashMap; import java.util.Map; import org.apache.tuscany.sca.management.ConfigAttributes; -import org.apache.tuscany.sca.node.Contribution; import org.apache.tuscany.sca.node.Node; import org.apache.tuscany.sca.node.NodeFactory; -import org.apache.tuscany.sca.node.impl.NodeFactoryImpl; +import org.apache.tuscany.sca.node.configuration.NodeConfiguration; public class DomainNode { @@ -37,8 +36,9 @@ public class DomainNode { public static final String DEFAULT_DOMAIN_NAME = "defaultDomain"; private ConfigAttributes configAttributes = new ConfigAttributesImpl(); + private String domainRegistryURI; - private NodeFactoryImpl nodeFactory; + private NodeFactory nodeFactory; private Map nodes = new HashMap(); public DomainNode() { @@ -46,11 +46,13 @@ public class DomainNode { } public DomainNode(String configURI) { + this.domainRegistryURI = configURI; parseConfigURI(configURI); start(); } public DomainNode(String configURI, String... contributionLocations) { + this.domainRegistryURI = configURI; parseConfigURI(configURI); start(); for (String loc : contributionLocations) { @@ -60,12 +62,10 @@ public class DomainNode { public void start() { if (nodeFactory != null) { - throw new IllegalStateException("Already started"); + throw new IllegalStateException("The node is already started"); } - //TODO shouldn't really be working with the impl - nodeFactory = (NodeFactoryImpl)NodeFactory.getInstance(configAttributes.getAttributes().get(DOMAIN_NAME_ATTR)); - nodeFactory.setConfigAttributes(configAttributes); + nodeFactory = NodeFactory.getInstance(configAttributes.getAttributes().get(DOMAIN_NAME_ATTR)); } public boolean isStarted() { @@ -74,17 +74,13 @@ public class DomainNode { public void stop() { if (nodeFactory == null) { - throw new IllegalStateException("not started"); + throw new IllegalStateException("The node is not started"); } for (Node node : nodes.values()) { node.stop(); } - -// TODO: stopping the node factory stops _all_ domain nodes not just this instance -// nodeFactory.destroy(); -// nodeFactory = null; -// nodes.clear(); + } public String addContribution(String location) { @@ -97,7 +93,11 @@ public class DomainNode { if (nodes.containsKey(uri)) { throw new IllegalArgumentException("contribution already added: " + uri); } - Node node = nodeFactory.createNode(new Contribution(uri, location)).start(); + NodeConfiguration configuration = + nodeFactory.createNodeConfiguration().addContribution(uri, location) + .setDomainRegistryURI(domainRegistryURI).setDomainURI(configAttributes.getAttributes() + .get(DOMAIN_NAME_ATTR)).setURI(uri); + Node node = nodeFactory.createNode(configuration).start(); nodes.put(uri, node); } diff --git a/java/sca/modules/domain-node/src/test/java/org/apache/tuscany/sca/domain/node/StopStartNodesTestCase.java b/java/sca/modules/domain-node/src/test/java/org/apache/tuscany/sca/domain/node/StopStartNodesTestCase.java index 52093129a8..3ee89b0a04 100644 --- a/java/sca/modules/domain-node/src/test/java/org/apache/tuscany/sca/domain/node/StopStartNodesTestCase.java +++ b/java/sca/modules/domain-node/src/test/java/org/apache/tuscany/sca/domain/node/StopStartNodesTestCase.java @@ -24,7 +24,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import itest.nodes.Helloworld; -import org.apache.tuscany.sca.domain.node.DomainNode; import org.junit.After; import org.junit.Test; import org.oasisopen.sca.client.SCAClient; @@ -58,7 +57,6 @@ public class StopStartNodesTestCase{ assertEquals("Hi Hello Petra", client.sayHello("Petra")); fail(); } catch (Exception e) { - e.printStackTrace(); // expected } diff --git a/java/sca/modules/endpoint-tribes/META-INF/MANIFEST.MF b/java/sca/modules/endpoint-tribes/META-INF/MANIFEST.MF index 09a4ff3301..8c7feecb30 100644 --- a/java/sca/modules/endpoint-tribes/META-INF/MANIFEST.MF +++ b/java/sca/modules/endpoint-tribes/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Bundle-DocURL: http://www.apache.org/ Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6 Import-Package: org.apache.catalina.tribes, org.apache.catalina.tribes.group, + org.apache.catalina.tribes.group.interceptors, org.apache.catalina.tribes.io, org.apache.catalina.tribes.membership, org.apache.catalina.tribes.tipis, diff --git a/java/sca/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java b/java/sca/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java index 823ecd51d0..09dcc011ee 100644 --- a/java/sca/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java +++ b/java/sca/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java @@ -20,12 +20,16 @@ package org.apache.tuscany.sca.endpoint.tribes; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.NetworkInterface; +import java.net.URI; import java.net.URL; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; @@ -36,11 +40,8 @@ import java.util.logging.Logger; import org.apache.catalina.tribes.Channel; import org.apache.catalina.tribes.ChannelException; -import org.apache.catalina.tribes.ChannelInterceptor; import org.apache.catalina.tribes.Member; -import org.apache.catalina.tribes.group.ChannelCoordinator; import org.apache.catalina.tribes.group.GroupChannel; -import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor; import org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor; import org.apache.catalina.tribes.membership.McastService; import org.apache.catalina.tribes.membership.StaticMember; @@ -48,10 +49,8 @@ import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.assembly.EndpointReference; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.LifeCycleListener; -import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.endpoint.tribes.AbstractReplicatedMap.MapEntry; import org.apache.tuscany.sca.endpoint.tribes.MapStore.MapListener; -import org.apache.tuscany.sca.management.ConfigAttributes; import org.apache.tuscany.sca.runtime.EndpointListener; import org.apache.tuscany.sca.runtime.EndpointRegistry; @@ -98,26 +97,50 @@ public class ReplicatedEndpointRegistry implements EndpointRegistry, LifeCycleLi return channel; } - public ReplicatedEndpointRegistry(ExtensionPointRegistry registry, Map attributes) { + public ReplicatedEndpointRegistry(ExtensionPointRegistry registry, + Map attributes, + String domainRegistryURI, + String domainURI) { this.registry = registry; + this.domainURI = domainURI; - UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); - ConfigAttributes domainConfig = utilities.getUtility(ConfigAttributes.class); - if (domainConfig != null) { - setConfig(domainConfig.getAttributes()); - } else { - setConfig(attributes); + getParameters(domainRegistryURI); + } + + private Map getParameters(String domainRegistryURI) { + Map map = new HashMap(); + URI uri = URI.create(domainRegistryURI); + map.put("address", uri.getHost()); + map.put("port", String.valueOf(uri.getPort())); + int index = domainRegistryURI.indexOf('?'); + if (index == -1) { + setConfig(map); + return map; + } + String query = domainRegistryURI.substring(index + 1); + try { + query = URLDecoder.decode(query, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e); + } + String[] params = query.split("&"); + for (String param : params) { + index = param.indexOf('='); + if (index != -1) { + map.put(param.substring(0, index), param.substring(index + 1)); + } } + setConfig(map); + return map; } private void setConfig(Map attributes) { - if (attributes.containsKey("domainName")) { - domainURI = attributes.get("domainName"); - } - String portStr = attributes.get("port"); if (portStr != null) { port = Integer.parseInt(portStr); + if (port == -1) { + port = MULTICAST_PORT; + } } String address = attributes.get("address"); if (address == null) { @@ -143,11 +166,6 @@ public class ReplicatedEndpointRegistry implements EndpointRegistry, LifeCycleLi } } - public ReplicatedEndpointRegistry(String domainURI) { - this.domainURI = domainURI; - // start(); - } - public void start() { if (map != null) { throw new IllegalStateException("The registry has already been started"); diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java index e92655146c..ca401a6484 100644 --- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java @@ -33,6 +33,8 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.tuscany.sca.extensibility.impl.LDAPFilter; + /** * Service discovery for Tuscany based on J2SE Jar service provider spec. * Services are described using configuration files in META-INF/services. @@ -152,9 +154,52 @@ public final class ServiceDiscovery implements ServiceDiscoverer { return sds; } + /** + * Discover all service providers that are compatible with the service type + * @param serviceType + * @return + * @throws IOException + */ public Collection getServiceDeclarations(Class serviceType) throws IOException { return getServiceDeclarations(serviceType, false); } + + /** + * Discover all service providers that are compatible with the service type and match the filter + * @param serviceType + * @param filter + * @return + * @throws IOException + */ + public Collection getServiceDeclarations(Class serviceType, String filter) throws IOException { + Collection sds = getServiceDeclarations(serviceType, false); + Collection filtered = new ArrayList(); + LDAPFilter filterImpl = LDAPFilter.newInstance(filter); + for(ServiceDeclaration sd: sds) { + if(filterImpl.match(sd.getAttributes())) { + filtered.add(sd); + } + } + return filtered; + } + + /** + * @param serviceName + * @param filter + * @return + * @throws IOException + */ + public Collection getServiceDeclarations(String serviceName, String filter) throws IOException { + Collection sds = getServiceDeclarations(serviceName, false); + Collection filtered = new ArrayList(); + LDAPFilter filterImpl = LDAPFilter.newInstance(filter); + for(ServiceDeclaration sd: sds) { + if(filterImpl.match(sd.getAttributes())) { + filtered.add(sd); + } + } + return filtered; + } public ServiceDeclaration getServiceDeclaration(Class serviceType) throws IOException { Collection sds = getServiceDeclarations(serviceType, true); diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java new file mode 100644 index 0000000000..77f6f3e8db --- /dev/null +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/InvalidSyntaxException.java @@ -0,0 +1,86 @@ +/* + * 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.extensibility.impl; + +/** + * A Framework exception used to indicate that a filter string has an invalid + * syntax. + * + *

+ * An InvalidSyntaxException object indicates that a filter + * string parameter has an invalid syntax and cannot be parsed. + * + *

+ * This exception conforms to the general purpose exception chaining mechanism. + * + */ + +public class InvalidSyntaxException extends RuntimeException { + static final long serialVersionUID = -4295194420816491875L; + /** + * The invalid filter string. + */ + private final String filter; + + /** + * Creates an exception of type InvalidSyntaxException. + * + *

+ * This method creates an InvalidSyntaxException object with + * the specified message and the filter string which generated the + * exception. + * + * @param msg The message. + * @param filter The invalid filter string. + */ + public InvalidSyntaxException(String msg, String filter) { + super(msg); + this.filter = filter; + } + + /** + * Creates an exception of type InvalidSyntaxException. + * + *

+ * This method creates an InvalidSyntaxException object with + * the specified message and the filter string which generated the + * exception. + * + * @param msg The message. + * @param filter The invalid filter string. + * @param cause The cause of this exception. + * @since 1.3 + */ + public InvalidSyntaxException(String msg, String filter, Throwable cause) { + super(msg, cause); + this.filter = filter; + } + + /** + * Returns the filter string that generated the + * InvalidSyntaxException object. + * + * @return The invalid filter string. + * @see BundleContext#getServiceReferences + * @see BundleContext#addServiceListener(ServiceListener,String) + */ + public String getFilter() { + return filter; + } +} \ No newline at end of file diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java new file mode 100644 index 0000000000..0390ef19d2 --- /dev/null +++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java @@ -0,0 +1,1355 @@ +package org.apache.tuscany.sca.extensibility.impl; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; + + +/** + * RFC 1960-based Filter. Filter objects can be created by calling the + * constructor with the desired filter string. A Filter object can be called + * numerous times to determine if the match argument matches the filter + * string that was used to create the Filter object. + * + *

+ * The syntax of a filter string is the string representation of LDAP search + * filters as defined in RFC 1960: A String Representation of LDAP Search + * Filters (available at http://www.ietf.org/rfc/rfc1960.txt). It should + * be noted that RFC 2254: A String Representation of LDAP Search + * Filters (available at http://www.ietf.org/rfc/rfc2254.txt) supersedes + * RFC 1960 but only adds extensible matching and is not applicable for this + * API. + * + *

+ * The string representation of an LDAP search filter is defined by the + * following grammar. It uses a prefix format. + * + *

+ *   <filter> ::= '(' <filtercomp> ')'
+ *   <filtercomp> ::= <and> | <or> | <not> | <item>
+ *   <and> ::= '&' <filterlist>
+ *   <or> ::= '|' <filterlist>
+ *   <not> ::= '!' <filter>
+ *   <filterlist> ::= <filter> | <filter> <filterlist>
+ *   <item> ::= <simple> | <present> | <substring>
+ *   <simple> ::= <attr> <filtertype> <value>
+ *   <filtertype> ::= <equal> | <approx> | <greater> | <less>
+ *   <equal> ::= '='
+ *   <approx> ::= '˜='
+ *   <greater> ::= '>='
+ *   <less> ::= '<='
+ *   <present> ::= <attr> '=*'
+ *   <substring> ::= <attr> '=' <initial> <any> <final>
+ *   <initial> ::= NULL | <value>
+ *   <any> ::= '*' <starval>
+ *   <starval> ::= NULL | <value> '*' <starval>
+ *   <final> ::= NULL | <value>
+ * 
+ * + * <attr> is a string representing an attribute, or key, + * in the properties objects of the registered services. Attribute names are + * not case sensitive; that is cn and CN both refer to the same attribute. + * <value> is a string representing the value, or part of + * one, of a key in the properties objects of the registered services. If a + * <value> must contain one of the characters ' + * *' or '(' or ')', these characters + * should be escaped by preceding them with the backslash '\' + * character. Note that although both the <substring> and + * <present> productions can produce the 'attr=*' + * construct, this construct is used only to denote a presence filter. + * + *

+ * Examples of LDAP filters are: + * + *

+ *   "(cn=Babs Jensen)"
+ *   "(!(cn=Tim Howes))"
+ *   "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
+ *   "(o=univ*of*mich*)"
+ * 
+ * + *

+ * The approximate match (~=) is implementation specific but + * should at least ignore case and white space differences. Optional are + * codes like soundex or other smart "closeness" comparisons. + * + *

+ * Comparison of values is not straightforward. Strings are compared + * differently than numbers and it is possible for a key to have multiple + * values. Note that that keys in the match argument must always be strings. + * The comparison is defined by the object type of the key's value. The + * following rules apply for comparison: + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Property Value Type Comparison Type
StringString comparison
Integer, Long, Float, Double, Byte, Short, BigInteger, BigDecimalnumerical comparison
Charactercharacter comparison
Booleanequality comparisons only
[] (array)recursively applied to values
Collectionrecursively applied to values
+ * Note: arrays of primitives are also supported.
+ * + * A filter matches a key that has multiple values if it matches at least + * one of those values. For example, + * + *
+ * Dictionary d = new Hashtable();
+ * d.put("cn", new String[] {"a", "b", "c"});
+ * 
+ * + * d will match (cn=a) and also (cn=b) + * + *

+ * A filter component that references a key having an unrecognizable data + * type will evaluate to false . + */ +public class LDAPFilter { + /* filter operators */ + private static final int EQUAL = 1; + private static final int APPROX = 2; + private static final int GREATER = 3; + private static final int LESS = 4; + private static final int PRESENT = 5; + private static final int SUBSTRING = 6; + private static final int AND = 7; + private static final int OR = 8; + private static final int NOT = 9; + + /** filter operation */ + private final int op; + /** filter attribute or null if operation AND, OR or NOT */ + private final String attr; + /** filter operands */ + private final Object value; + + /* normalized filter string for Filter object */ + private transient volatile String filterString; + + /** + * Constructs a {@link LDAPFilter} object. This filter object may be + * used to match a {@link ServiceReference} or a Dictionary. + * + *

+ * If the filter cannot be parsed, an {@link InvalidSyntaxException} + * will be thrown with a human readable message where the filter became + * unparsable. + * + * @param filterString the filter string. + * @exception InvalidSyntaxException If the filter parameter contains an + * invalid filter string that cannot be parsed. + */ + public static LDAPFilter newInstance(String filterString) throws InvalidSyntaxException { + return new Parser(filterString).parse(); + } + + LDAPFilter(int operation, String attr, Object value) { + this.op = operation; + this.attr = attr; + this.value = value; + } + + /** + * Filter using a Dictionary. This Filter is + * executed using the specified Dictionary's keys and + * values. The keys are case insensitively matched with this + * Filter. + * + * @param dictionary The Dictionary whose keys are used in + * the match. + * @return true if the Dictionary's keys and + * values match this filter; false otherwise. + * @throws IllegalArgumentException If dictionary contains + * case variants of the same key name. + */ + public boolean match(Dictionary dictionary) { + return match0(new CaseInsensitiveDictionary(dictionary)); + } + + public boolean match(Map map) { + Properties props = new Properties(); + props.putAll(map); + return match0(new CaseInsensitiveDictionary(props)); + } + + public static boolean matches(ServiceDeclaration declaration, String filter) { + if (filter == null) { + return true; + } + LDAPFilter filterImpl = newInstance(filter); + return filterImpl.match(declaration.getAttributes()); + } + + /** + * Filter with case sensitivity using a Dictionary. This + * Filter is executed using the specified + * Dictionary's keys and values. The keys are case + * sensitively matched with this Filter. + * + * @param dictionary The Dictionary whose keys are used in + * the match. + * @return true if the Dictionary's keys and + * values match this filter; false otherwise. + * @since 1.3 + */ + public boolean matchCase(Dictionary dictionary) { + return match0(dictionary); + } + + /** + * Returns this Filter's filter string. + *

+ * The filter string is normalized by removing whitespace which does not + * affect the meaning of the filter. + * + * @return This Filter's filter string. + */ + public String toString() { + String result = filterString; + if (result == null) { + filterString = result = normalize(); + } + return result; + } + + /** + * Returns this Filter's normalized filter string. + *

+ * The filter string is normalized by removing whitespace which does not + * affect the meaning of the filter. + * + * @return This Filter's filter string. + */ + private String normalize() { + StringBuffer sb = new StringBuffer(); + sb.append('('); + + switch (op) { + case AND: { + sb.append('&'); + + LDAPFilter[] filters = (LDAPFilter[])value; + for (int i = 0, size = filters.length; i < size; i++) { + sb.append(filters[i].normalize()); + } + + break; + } + + case OR: { + sb.append('|'); + + LDAPFilter[] filters = (LDAPFilter[])value; + for (int i = 0, size = filters.length; i < size; i++) { + sb.append(filters[i].normalize()); + } + + break; + } + + case NOT: { + sb.append('!'); + LDAPFilter filter = (LDAPFilter)value; + sb.append(filter.normalize()); + + break; + } + + case SUBSTRING: { + sb.append(attr); + sb.append('='); + + String[] substrings = (String[])value; + + for (int i = 0, size = substrings.length; i < size; i++) { + String substr = substrings[i]; + + if (substr == null) /* * */{ + sb.append('*'); + } else /* xxx */{ + sb.append(encodeValue(substr)); + } + } + + break; + } + case EQUAL: { + sb.append(attr); + sb.append('='); + sb.append(encodeValue((String)value)); + + break; + } + case GREATER: { + sb.append(attr); + sb.append(">="); + sb.append(encodeValue((String)value)); + + break; + } + case LESS: { + sb.append(attr); + sb.append("<="); + sb.append(encodeValue((String)value)); + + break; + } + case APPROX: { + sb.append(attr); + sb.append("~="); + sb.append(encodeValue(approxString((String)value))); + + break; + } + + case PRESENT: { + sb.append(attr); + sb.append("=*"); + + break; + } + } + + sb.append(')'); + + return sb.toString(); + } + + /** + * Compares this Filter to another Filter. + * + *

+ * This implementation returns the result of calling + * this.toString().equals(obj.toString(). + * + * @param obj The object to compare against this Filter. + * @return If the other object is a Filter object, then + * returns the result of calling + * this.toString().equals(obj.toString(); + * false otherwise. + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof LDAPFilter)) { + return false; + } + + return this.toString().equals(obj.toString()); + } + + /** + * Returns the hashCode for this Filter. + * + *

+ * This implementation returns the result of calling + * this.toString().hashCode(). + * + * @return The hashCode of this Filter. + */ + public int hashCode() { + return this.toString().hashCode(); + } + + /** + * Internal match routine. Dictionary parameter must support + * case-insensitive get. + * + * @param properties A dictionary whose keys are used in the match. + * @return If the Dictionary's keys match the filter, return + * true. Otherwise, return false. + */ + private boolean match0(Dictionary properties) { + switch (op) { + case AND: { + LDAPFilter[] filters = (LDAPFilter[])value; + for (int i = 0, size = filters.length; i < size; i++) { + if (!filters[i].match0(properties)) { + return false; + } + } + + return true; + } + + case OR: { + LDAPFilter[] filters = (LDAPFilter[])value; + for (int i = 0, size = filters.length; i < size; i++) { + if (filters[i].match0(properties)) { + return true; + } + } + + return false; + } + + case NOT: { + LDAPFilter filter = (LDAPFilter)value; + + return !filter.match0(properties); + } + + case SUBSTRING: + case EQUAL: + case GREATER: + case LESS: + case APPROX: { + Object prop = (properties == null) ? null : properties.get(attr); + + return compare(op, prop, value); + } + + case PRESENT: { + Object prop = (properties == null) ? null : properties.get(attr); + + return prop != null; + } + } + + return false; + } + + /** + * Encode the value string such that '(', '*', ')' and '\' are escaped. + * + * @param value unencoded value string. + * @return encoded value string. + */ + private static String encodeValue(String value) { + boolean encoded = false; + int inlen = value.length(); + int outlen = inlen << 1; /* inlen 2 */ + + char[] output = new char[outlen]; + value.getChars(0, inlen, output, inlen); + + int cursor = 0; + for (int i = inlen; i < outlen; i++) { + char c = output[i]; + + switch (c) { + case '(': + case '*': + case ')': + case '\\': { + output[cursor] = '\\'; + cursor++; + encoded = true; + + break; + } + } + + output[cursor] = c; + cursor++; + } + + return encoded ? new String(output, 0, cursor) : value; + } + + private boolean compare(int operation, Object value1, Object value2) { + if (value1 == null) { + return false; + } + if (value1 instanceof String) { + return compare_String(operation, (String)value1, value2); + } + + Class clazz = value1.getClass(); + if (clazz.isArray()) { + Class type = clazz.getComponentType(); + if (type.isPrimitive()) { + return compare_PrimitiveArray(operation, type, value1, value2); + } + return compare_ObjectArray(operation, (Object[])value1, value2); + } + if (value1 instanceof Collection) { + return compare_Collection(operation, (Collection)value1, value2); + } + if (value1 instanceof Integer) { + return compare_Integer(operation, ((Integer)value1).intValue(), value2); + } + if (value1 instanceof Long) { + return compare_Long(operation, ((Long)value1).longValue(), value2); + } + if (value1 instanceof Byte) { + return compare_Byte(operation, ((Byte)value1).byteValue(), value2); + } + if (value1 instanceof Short) { + return compare_Short(operation, ((Short)value1).shortValue(), value2); + } + if (value1 instanceof Character) { + return compare_Character(operation, ((Character)value1).charValue(), value2); + } + if (value1 instanceof Float) { + return compare_Float(operation, ((Float)value1).floatValue(), value2); + } + if (value1 instanceof Double) { + return compare_Double(operation, ((Double)value1).doubleValue(), value2); + } + if (value1 instanceof Boolean) { + return compare_Boolean(operation, ((Boolean)value1).booleanValue(), value2); + } + if (value1 instanceof Comparable) { + return compare_Comparable(operation, (Comparable)value1, value2); + } + return compare_Unknown(operation, value1, value2); // RFC 59 + } + + private boolean compare_Collection(int operation, Collection collection, Object value2) { + for (Iterator iterator = collection.iterator(); iterator.hasNext();) { + if (compare(operation, iterator.next(), value2)) { + return true; + } + } + return false; + } + + private boolean compare_ObjectArray(int operation, Object[] array, Object value2) { + for (int i = 0, size = array.length; i < size; i++) { + if (compare(operation, array[i], value2)) { + return true; + } + } + return false; + } + + private boolean compare_PrimitiveArray(int operation, Class type, Object primarray, Object value2) { + if (Integer.TYPE.isAssignableFrom(type)) { + int[] array = (int[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Integer(operation, array[i], value2)) { + return true; + } + } + return false; + } + if (Long.TYPE.isAssignableFrom(type)) { + long[] array = (long[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Long(operation, array[i], value2)) { + return true; + } + } + return false; + } + if (Byte.TYPE.isAssignableFrom(type)) { + byte[] array = (byte[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Byte(operation, array[i], value2)) { + return true; + } + } + return false; + } + if (Short.TYPE.isAssignableFrom(type)) { + short[] array = (short[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Short(operation, array[i], value2)) { + return true; + } + } + return false; + } + if (Character.TYPE.isAssignableFrom(type)) { + char[] array = (char[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Character(operation, array[i], value2)) { + return true; + } + } + return false; + } + if (Float.TYPE.isAssignableFrom(type)) { + float[] array = (float[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Float(operation, array[i], value2)) { + return true; + } + } + return false; + } + if (Double.TYPE.isAssignableFrom(type)) { + double[] array = (double[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Double(operation, array[i], value2)) { + return true; + } + } + return false; + } + if (Boolean.TYPE.isAssignableFrom(type)) { + boolean[] array = (boolean[])primarray; + for (int i = 0, size = array.length; i < size; i++) { + if (compare_Boolean(operation, array[i], value2)) { + return true; + } + } + return false; + } + return false; + } + + private boolean compare_String(int operation, String string, Object value2) { + switch (operation) { + case SUBSTRING: { + String[] substrings = (String[])value2; + int pos = 0; + for (int i = 0, size = substrings.length; i < size; i++) { + String substr = substrings[i]; + + if (i + 1 < size) /* if this is not that last substr */{ + if (substr == null) /* * */{ + String substr2 = substrings[i + 1]; + + if (substr2 == null) /* ** */ + continue; /* ignore first star */ + /* xxx */ + int index = string.indexOf(substr2, pos); + if (index == -1) { + return false; + } + + pos = index + substr2.length(); + if (i + 2 < size) // if there are more + // substrings, increment + // over the string we just + // matched; otherwise need + // to do the last substr + // check + i++; + } else /* xxx */{ + int len = substr.length(); + if (string.regionMatches(pos, substr, 0, len)) { + pos += len; + } else { + return false; + } + } + } else /* last substr */{ + if (substr == null) /* * */{ + return true; + } + /* xxx */ + return string.endsWith(substr); + } + } + + return true; + } + case EQUAL: { + return string.equals(value2); + } + case APPROX: { + string = approxString(string); + String string2 = approxString((String)value2); + + return string.equalsIgnoreCase(string2); + } + case GREATER: { + return string.compareTo((String)value2) >= 0; + } + case LESS: { + return string.compareTo((String)value2) <= 0; + } + } + return false; + } + + private boolean compare_Integer(int operation, int intval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + int intval2 = Integer.parseInt(((String)value2).trim()); + switch (operation) { + case APPROX: + case EQUAL: { + return intval == intval2; + } + case GREATER: { + return intval >= intval2; + } + case LESS: { + return intval <= intval2; + } + } + return false; + } + + private boolean compare_Long(int operation, long longval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + long longval2 = Long.parseLong(((String)value2).trim()); + switch (operation) { + case APPROX: + case EQUAL: { + return longval == longval2; + } + case GREATER: { + return longval >= longval2; + } + case LESS: { + return longval <= longval2; + } + } + return false; + } + + private boolean compare_Byte(int operation, byte byteval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + byte byteval2 = Byte.parseByte(((String)value2).trim()); + switch (operation) { + case APPROX: + case EQUAL: { + return byteval == byteval2; + } + case GREATER: { + return byteval >= byteval2; + } + case LESS: { + return byteval <= byteval2; + } + } + return false; + } + + private boolean compare_Short(int operation, short shortval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + short shortval2 = Short.parseShort(((String)value2).trim()); + switch (operation) { + case APPROX: + case EQUAL: { + return shortval == shortval2; + } + case GREATER: { + return shortval >= shortval2; + } + case LESS: { + return shortval <= shortval2; + } + } + return false; + } + + private boolean compare_Character(int operation, char charval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + char charval2 = (((String)value2).trim()).charAt(0); + switch (operation) { + case EQUAL: { + return charval == charval2; + } + case APPROX: { + return (charval == charval2) || (Character.toUpperCase(charval) == Character.toUpperCase(charval2)) + || (Character.toLowerCase(charval) == Character.toLowerCase(charval2)); + } + case GREATER: { + return charval >= charval2; + } + case LESS: { + return charval <= charval2; + } + } + return false; + } + + private boolean compare_Boolean(int operation, boolean boolval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + boolean boolval2 = Boolean.valueOf(((String)value2).trim()).booleanValue(); + switch (operation) { + case APPROX: + case EQUAL: + case GREATER: + case LESS: { + return boolval == boolval2; + } + } + return false; + } + + private boolean compare_Float(int operation, float floatval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + float floatval2 = Float.parseFloat(((String)value2).trim()); + switch (operation) { + case APPROX: + case EQUAL: { + return Float.compare(floatval, floatval2) == 0; + } + case GREATER: { + return Float.compare(floatval, floatval2) >= 0; + } + case LESS: { + return Float.compare(floatval, floatval2) <= 0; + } + } + return false; + } + + private boolean compare_Double(int operation, double doubleval, Object value2) { + if (operation == SUBSTRING) { + return false; + } + double doubleval2 = Double.parseDouble(((String)value2).trim()); + switch (operation) { + case APPROX: + case EQUAL: { + return Double.compare(doubleval, doubleval2) == 0; + } + case GREATER: { + return Double.compare(doubleval, doubleval2) >= 0; + } + case LESS: { + return Double.compare(doubleval, doubleval2) <= 0; + } + } + return false; + } + + private static final Class[] constructorType = new Class[] {String.class}; + + private boolean compare_Comparable(int operation, Comparable value1, Object value2) { + if (operation == SUBSTRING) { + return false; + } + Constructor constructor; + try { + constructor = value1.getClass().getConstructor(constructorType); + } catch (NoSuchMethodException e) { + return false; + } + try { + if (!constructor.isAccessible()) + AccessController.doPrivileged(new SetAccessibleAction(constructor)); + value2 = constructor.newInstance(new Object[] {((String)value2).trim()}); + } catch (IllegalAccessException e) { + return false; + } catch (InvocationTargetException e) { + return false; + } catch (InstantiationException e) { + return false; + } + + switch (operation) { + case APPROX: + case EQUAL: { + return value1.compareTo(value2) == 0; + } + case GREATER: { + return value1.compareTo(value2) >= 0; + } + case LESS: { + return value1.compareTo(value2) <= 0; + } + } + return false; + } + + private boolean compare_Unknown(int operation, Object value1, Object value2) { + if (operation == SUBSTRING) { + return false; + } + Constructor constructor; + try { + constructor = value1.getClass().getConstructor(constructorType); + } catch (NoSuchMethodException e) { + return false; + } + try { + if (!constructor.isAccessible()) + AccessController.doPrivileged(new SetAccessibleAction(constructor)); + value2 = constructor.newInstance(new Object[] {((String)value2).trim()}); + } catch (IllegalAccessException e) { + return false; + } catch (InvocationTargetException e) { + return false; + } catch (InstantiationException e) { + return false; + } + + switch (operation) { + case APPROX: + case EQUAL: + case GREATER: + case LESS: { + return value1.equals(value2); + } + } + return false; + } + + /** + * Map a string for an APPROX (~=) comparison. + * + * This implementation removes white spaces. This is the minimum + * implementation allowed by the OSGi spec. + * + * @param input Input string. + * @return String ready for APPROX comparison. + */ + private static String approxString(String input) { + boolean changed = false; + char[] output = input.toCharArray(); + int cursor = 0; + for (int i = 0, length = output.length; i < length; i++) { + char c = output[i]; + + if (Character.isWhitespace(c)) { + changed = true; + continue; + } + + output[cursor] = c; + cursor++; + } + + return changed ? new String(output, 0, cursor) : input; + } + + /** + * Parser class for OSGi filter strings. This class parses the complete + * filter string and builds a tree of Filter objects rooted at the + * parent. + */ + private static class Parser { + private final String filterstring; + private final char[] filterChars; + private int pos; + + Parser(String filterstring) { + this.filterstring = filterstring; + filterChars = filterstring.toCharArray(); + pos = 0; + } + + LDAPFilter parse() throws InvalidSyntaxException { + LDAPFilter filter; + try { + filter = parse_filter(); + } catch (ArrayIndexOutOfBoundsException e) { + throw new InvalidSyntaxException("Filter ended abruptly", filterstring); + } + + if (pos != filterChars.length) { + throw new InvalidSyntaxException("Extraneous trailing characters: " + filterstring.substring(pos), + filterstring); + } + return filter; + } + + private LDAPFilter parse_filter() throws InvalidSyntaxException { + LDAPFilter filter; + skipWhiteSpace(); + + if (filterChars[pos] != '(') { + throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); + } + + pos++; + + filter = parse_filtercomp(); + + skipWhiteSpace(); + + if (filterChars[pos] != ')') { + throw new InvalidSyntaxException("Missing ')': " + filterstring.substring(pos), filterstring); + } + + pos++; + + skipWhiteSpace(); + + return filter; + } + + private LDAPFilter parse_filtercomp() throws InvalidSyntaxException { + skipWhiteSpace(); + + char c = filterChars[pos]; + + switch (c) { + case '&': { + pos++; + return parse_and(); + } + case '|': { + pos++; + return parse_or(); + } + case '!': { + pos++; + return parse_not(); + } + } + return parse_item(); + } + + private LDAPFilter parse_and() throws InvalidSyntaxException { + skipWhiteSpace(); + + if (filterChars[pos] != '(') { + throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); + } + + List operands = new ArrayList(10); + + while (filterChars[pos] == '(') { + LDAPFilter child = parse_filter(); + operands.add(child); + } + + return new LDAPFilter(LDAPFilter.AND, null, operands.toArray(new LDAPFilter[operands.size()])); + } + + private LDAPFilter parse_or() throws InvalidSyntaxException { + skipWhiteSpace(); + + if (filterChars[pos] != '(') { + throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); + } + + List operands = new ArrayList(10); + + while (filterChars[pos] == '(') { + LDAPFilter child = parse_filter(); + operands.add(child); + } + + return new LDAPFilter(LDAPFilter.OR, null, operands.toArray(new LDAPFilter[operands.size()])); + } + + private LDAPFilter parse_not() throws InvalidSyntaxException { + skipWhiteSpace(); + + if (filterChars[pos] != '(') { + throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); + } + + LDAPFilter child = parse_filter(); + + return new LDAPFilter(LDAPFilter.NOT, null, child); + } + + private LDAPFilter parse_item() throws InvalidSyntaxException { + String attr = parse_attr(); + + skipWhiteSpace(); + + switch (filterChars[pos]) { + case '~': { + if (filterChars[pos + 1] == '=') { + pos += 2; + return new LDAPFilter(LDAPFilter.APPROX, attr, parse_value()); + } + break; + } + case '>': { + if (filterChars[pos + 1] == '=') { + pos += 2; + return new LDAPFilter(LDAPFilter.GREATER, attr, parse_value()); + } + break; + } + case '<': { + if (filterChars[pos + 1] == '=') { + pos += 2; + return new LDAPFilter(LDAPFilter.LESS, attr, parse_value()); + } + break; + } + case '=': { + if (filterChars[pos + 1] == '*') { + int oldpos = pos; + pos += 2; + skipWhiteSpace(); + if (filterChars[pos] == ')') { + return new LDAPFilter(LDAPFilter.PRESENT, attr, null); + } + pos = oldpos; + } + + pos++; + Object string = parse_substring(); + + if (string instanceof String) { + return new LDAPFilter(LDAPFilter.EQUAL, attr, string); + } + return new LDAPFilter(LDAPFilter.SUBSTRING, attr, string); + } + } + + throw new InvalidSyntaxException("Invalid operator: " + filterstring.substring(pos), filterstring); + } + + private String parse_attr() throws InvalidSyntaxException { + skipWhiteSpace(); + + int begin = pos; + int end = pos; + + char c = filterChars[pos]; + + while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') { + pos++; + + if (!Character.isWhitespace(c)) { + end = pos; + } + + c = filterChars[pos]; + } + + int length = end - begin; + + if (length == 0) { + throw new InvalidSyntaxException("Missing attr: " + filterstring.substring(pos), filterstring); + } + + return new String(filterChars, begin, length); + } + + private String parse_value() throws InvalidSyntaxException { + StringBuffer sb = new StringBuffer(filterChars.length - pos); + + parseloop: while (true) { + char c = filterChars[pos]; + + switch (c) { + case ')': { + break parseloop; + } + + case '(': { + throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), + filterstring); + } + + case '\\': { + pos++; + c = filterChars[pos]; + /* fall through into default */ + } + + default: { + sb.append(c); + pos++; + break; + } + } + } + + if (sb.length() == 0) { + throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring); + } + + return sb.toString(); + } + + private Object parse_substring() throws InvalidSyntaxException { + StringBuffer sb = new StringBuffer(filterChars.length - pos); + + List operands = new ArrayList(10); + + parseloop: while (true) { + char c = filterChars[pos]; + + switch (c) { + case ')': { + if (sb.length() > 0) { + operands.add(sb.toString()); + } + + break parseloop; + } + + case '(': { + throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), + filterstring); + } + + case '*': { + if (sb.length() > 0) { + operands.add(sb.toString()); + } + + sb.setLength(0); + + operands.add(null); + pos++; + + break; + } + + case '\\': { + pos++; + c = filterChars[pos]; + /* fall through into default */ + } + + default: { + sb.append(c); + pos++; + break; + } + } + } + + int size = operands.size(); + + if (size == 0) { + throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring); + } + + if (size == 1) { + Object single = operands.get(0); + + if (single != null) { + return single; + } + } + + return operands.toArray(new String[size]); + } + + private void skipWhiteSpace() { + for (int length = filterChars.length; (pos < length) && Character.isWhitespace(filterChars[pos]);) { + pos++; + } + } + } + + /** + * This Dictionary is used for case-insensitive key lookup during filter + * evaluation. This Dictionary implementation only supports the get + * operation using a String key as no other operations are used by the + * Filter implementation. + */ + static class CaseInsensitiveDictionary extends Dictionary { + private final Dictionary dictionary; + private final String[] keys; + + /** + * Create a case insensitive dictionary from the specified dictionary. + * + * @param dictionary + * @throws IllegalArgumentException If dictionary contains + * case variants of the same key name. + */ + CaseInsensitiveDictionary(Dictionary dictionary) { + if (dictionary == null) { + this.dictionary = null; + this.keys = new String[0]; + return; + } + this.dictionary = dictionary; + List keyList = new ArrayList(dictionary.size()); + for (Enumeration e = dictionary.keys(); e.hasMoreElements();) { + Object k = e.nextElement(); + if (k instanceof String) { + String key = (String)k; + for (Iterator i = keyList.iterator(); i.hasNext();) { + if (key.equalsIgnoreCase((String)i.next())) { + throw new IllegalArgumentException(); + } + } + keyList.add(key); + } + } + this.keys = (String[])keyList.toArray(new String[keyList.size()]); + } + + public Object get(Object o) { + String k = (String)o; + for (int i = 0, length = keys.length; i < length; i++) { + String key = keys[i]; + if (key.equalsIgnoreCase(k)) { + return dictionary.get(key); + } + } + return null; + } + + public boolean isEmpty() { + throw new UnsupportedOperationException(); + } + + public Enumeration keys() { + throw new UnsupportedOperationException(); + } + + public Enumeration elements() { + throw new UnsupportedOperationException(); + } + + public Object put(Object key, Object value) { + throw new UnsupportedOperationException(); + } + + public Object remove(Object key) { + throw new UnsupportedOperationException(); + } + + public int size() { + throw new UnsupportedOperationException(); + } + } + + static class SetAccessibleAction implements PrivilegedAction { + private final AccessibleObject accessible; + + SetAccessibleAction(AccessibleObject accessible) { + this.accessible = accessible; + } + + public Object run() { + accessible.setAccessible(true); + return null; + } + } +} \ No newline at end of file diff --git a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/DefaultMonitorFactory.java b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/DefaultMonitorFactory.java index 6bd796f3c1..a92bb89084 100644 --- a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/DefaultMonitorFactory.java +++ b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/DefaultMonitorFactory.java @@ -27,14 +27,32 @@ import org.apache.tuscany.sca.monitor.impl.MonitorImpl; * @version $Rev$ $Date$ */ public class DefaultMonitorFactory implements MonitorFactory { + private ThreadLocal contextMonitor = new InheritableThreadLocal(); - private Monitor monitor = null; - + // [HACK] This is a hack to reuse the same monitor on the thread public Monitor createMonitor() { + return getContextMonitor(true); + // return new MonitorImpl(); + } + + public Monitor getContextMonitor() { + return contextMonitor.get(); + } + + public Monitor getContextMonitor(boolean create) { + Monitor monitor = contextMonitor.get(); if (monitor == null) { monitor = new MonitorImpl(); + setContextMonitor(monitor); } return monitor; } + public void removeContextMonitor() { + contextMonitor.remove(); + } + + public void setContextMonitor(Monitor value) { + contextMonitor.set(value); + } } diff --git a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/Monitor.java b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/Monitor.java index 5129410e54..581d3d3c38 100644 --- a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/Monitor.java +++ b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/Monitor.java @@ -120,6 +120,11 @@ public abstract class Monitor { */ public abstract void clearContext(); + /** + * Clear context and problems + */ + public abstract void reset(); + /** * A utility function for raising a warning. It creates the problem and * adds it to the monitor diff --git a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/MonitorFactory.java b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/MonitorFactory.java index 3f2acaaf07..9309d4b293 100644 --- a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/MonitorFactory.java +++ b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/MonitorFactory.java @@ -18,6 +18,7 @@ */ package org.apache.tuscany.sca.monitor; + /** * A factory for validation monitors * @@ -32,4 +33,27 @@ public interface MonitorFactory { */ Monitor createMonitor(); + /** + * Get the monitor instance on the thread + * @return the monitor instance on the thread + */ + Monitor getContextMonitor(); + + /** + * Get the monitor instance on the thread + * @param create if it true, then create a new instance if no monitor is on the thread + * @return the monitor instance on the thread + */ + Monitor getContextMonitor(boolean create); + + /** + * Remove the monitor on the thread + */ + void removeContextMonitor(); + + /** + * Set the monitor onto the thread + * @param value + */ + void setContextMonitor(Monitor monitor); } diff --git a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/impl/MonitorImpl.java b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/impl/MonitorImpl.java index 74022c62db..523a63b819 100644 --- a/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/impl/MonitorImpl.java +++ b/java/sca/modules/monitor/src/main/java/org/apache/tuscany/sca/monitor/impl/MonitorImpl.java @@ -129,4 +129,11 @@ public class MonitorImpl extends Monitor { public void clearContext() { contextStack.clear(); } + + @Override + public void reset() { + clearContext(); + problemCache.clear(); + artifactName = null; + } } diff --git a/java/sca/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java b/java/sca/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java index d9c88d3071..a82e4a3816 100644 --- a/java/sca/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java +++ b/java/sca/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java @@ -26,15 +26,15 @@ import org.apache.tuscany.sca.assembly.Implementation; import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.implementation.osgi.OSGiImplementation; import org.apache.tuscany.sca.osgi.service.remoteadmin.EndpointDescription; +import org.apache.tuscany.sca.runtime.DomainRegistryFactory; import org.apache.tuscany.sca.runtime.EndpointListener; -import org.apache.tuscany.sca.runtime.EndpointRegistry; import org.osgi.framework.BundleContext; /** * Discovery service based on the distributed SCA domain */ public class DomainDiscoveryService extends AbstractDiscoveryService implements EndpointListener { - private EndpointRegistry endpointRegistry; + private DomainRegistryFactory domainRegistryFactory; public DomainDiscoveryService(BundleContext context) { super(context); @@ -43,9 +43,9 @@ public class DomainDiscoveryService extends AbstractDiscoveryService implements public void start() { super.start(); getExtensionPointRegistry(); - this.endpointRegistry = - registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(EndpointRegistry.class); - this.endpointRegistry.addListener(this); + this.domainRegistryFactory = + registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(DomainRegistryFactory.class); + domainRegistryFactory.addListener(this); } public void endpointAdded(Endpoint endpoint) { @@ -102,7 +102,7 @@ public class DomainDiscoveryService extends AbstractDiscoveryService implements } public void stop() { - endpointRegistry.removeListener(this); + domainRegistryFactory.removeListener(this); super.stop(); } diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/CompositeContextImpl.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/CompositeContextImpl.java index 54acece3cc..604bb502f9 100644 --- a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/CompositeContextImpl.java +++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/CompositeContextImpl.java @@ -20,6 +20,7 @@ package org.apache.tuscany.sca.node.impl; import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.EndpointReference; import org.apache.tuscany.sca.context.ComponentContextFactory; import org.apache.tuscany.sca.context.CompositeContext; import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint; @@ -58,6 +59,10 @@ public class CompositeContextImpl extends CompositeContext { (RuntimeComponentContext)componentContextFactory.createComponentContext(this, runtimeComponent); runtimeComponent.setComponentContext(componentContext); } + + public void bindEndpointReference(EndpointReference endpointReference) { + + } public Composite getDomainComposite() { return domainComposite; diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java index 052f15b2dc..6ac8394b8f 100644 --- a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java +++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java @@ -54,7 +54,6 @@ import org.apache.tuscany.sca.assembly.Composite; import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; import org.apache.tuscany.sca.assembly.builder.CompositeBuilder; import org.apache.tuscany.sca.assembly.builder.DeployedCompositeBuilder; -import org.apache.tuscany.sca.assembly.builder.EndpointReferenceBuilder; import org.apache.tuscany.sca.common.xml.stax.StAXHelper; import org.apache.tuscany.sca.contribution.Artifact; import org.apache.tuscany.sca.contribution.Contribution; @@ -88,7 +87,6 @@ import org.apache.tuscany.sca.definitions.util.DefinitionsUtil; import org.apache.tuscany.sca.definitions.xml.DefinitionsExtensionPoint; import org.apache.tuscany.sca.extensibility.ServiceDeclaration; import org.apache.tuscany.sca.extensibility.ServiceDiscovery; -import org.apache.tuscany.sca.management.ConfigAttributes; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.monitor.MonitorFactory; import org.apache.tuscany.sca.monitor.Problem; @@ -117,23 +115,23 @@ public class NodeFactoryImpl extends NodeFactory { private StAXArtifactProcessor compositeProcessor; private ContributionFactory contributionFactory; private ExtendedURLArtifactProcessor contributionProcessor; - private EndpointReferenceBuilder endpointReferenceBuilder; protected ExtensionPointRegistry extensionPoints; private XMLInputFactory inputFactory; protected FactoryExtensionPoint modelFactories; private ModelResolverExtensionPoint modelResolvers; - private Monitor monitor; protected ProxyFactory proxyFactory; private Contribution systemContribution; private Definitions systemDefinitions; private StAXArtifactProcessorExtensionPoint xmlProcessors; + + protected MonitorFactory monitorFactory; + /** * Automatically destroy the factory when last node is stopped. Subclasses * can set this flag. */ protected boolean autoDestroy = true; - private ConfigAttributes configAttributes; @Override public Node createNode(NodeConfiguration configuration) { @@ -276,15 +274,20 @@ public class NodeFactoryImpl extends NodeFactory { * * @throws Exception */ - private void analyzeProblems() throws Throwable { - for (Problem problem : monitor.getProblems()) { - if ((problem.getSeverity() == Severity.ERROR)) { - if (problem.getCause() != null) { - throw problem.getCause(); - } else { - throw new ServiceRuntimeException(problem.toString()); + private void analyzeProblems(Monitor monitor) throws Throwable { + try { + for (Problem problem : monitor.getProblems()) { + if ((problem.getSeverity() == Severity.ERROR)) { + if (problem.getCause() != null) { + throw problem.getCause(); + } else { + throw new ServiceRuntimeException(problem.toString()); + } } } + } finally { + // FIXME: Clear problems so that the monitor is clean again + monitor.reset(); } } @@ -390,13 +393,8 @@ public class NodeFactoryImpl extends NodeFactory { // Create a monitor UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); - - if (configAttributes != null) { - utilities.addUtility(ConfigAttributes.class, configAttributes); - } - MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); - monitor = monitorFactory.createMonitor(); + monitorFactory = utilities.getUtility(MonitorFactory.class); // Initialize the Tuscany module activators // The module activators will be started @@ -423,9 +421,6 @@ public class NodeFactoryImpl extends NodeFactory { BuilderExtensionPoint compositeBuilders = extensionPoints.getExtensionPoint(BuilderExtensionPoint.class); compositeBuilder = compositeBuilders.getCompositeBuilder("org.apache.tuscany.sca.assembly.builder.CompositeBuilder"); - // Get endpoint builder - endpointReferenceBuilder = utilities.getUtility(EndpointReferenceBuilder.class); - // Initialize runtime // Get proxy factory @@ -438,11 +433,15 @@ public class NodeFactoryImpl extends NodeFactory { systemDefinitions = definitionsFactory.createDefinitions(); DefinitionsExtensionPoint definitionsExtensionPoint = extensionPoints.getExtensionPoint(DefinitionsExtensionPoint.class); + Monitor monitor = monitorFactory.createMonitor(); monitor.pushContext("Extension points definitions"); - for(Definitions defs: definitionsExtensionPoint.getDefinitions()) { - DefinitionsUtil.aggregate(defs, systemDefinitions, monitor); + try { + for (Definitions defs : definitionsExtensionPoint.getDefinitions()) { + DefinitionsUtil.aggregate(defs, systemDefinitions, monitor); + } + } finally { + monitor.popContext(); } - monitor.popContext(); // create a system contribution to hold the definitions. The contribution // will be extended later with definitions from application contributions @@ -474,11 +473,11 @@ public class NodeFactoryImpl extends NodeFactory { return new DefaultExtensionPointRegistry(); } - protected Composite configureNode(NodeConfiguration configuration, List contributions) + protected Composite configureNode(NodeConfiguration configuration, List contributions, Monitor monitor) throws Throwable { if (contributions == null) { // Load contributions - contributions = loadContributions(configuration); + contributions = loadContributions(configuration, monitor); } // Build an aggregated SCA definitions model. Must be done before we try and // resolve any contributions or composites as they may depend on the full @@ -558,15 +557,12 @@ public class NodeFactoryImpl extends NodeFactory { // build the top level composite ((DeployedCompositeBuilder)compositeBuilder).build(domainComposite, systemDefinitions, bindingMap, monitor); - analyzeProblems(); - - endpointReferenceBuilder.buildtimeBuild(domainComposite); - analyzeProblems(); + analyzeProblems(monitor); return domainComposite; } - private List loadContributions(NodeConfiguration configuration) throws Throwable { + private List loadContributions(NodeConfiguration configuration, Monitor monitor) throws Throwable { List contributions = new ArrayList(); // Load the specified contributions @@ -619,7 +615,7 @@ public class NodeFactoryImpl extends NodeFactory { } } } - analyzeProblems(); + analyzeProblems(monitor); } return contributions; } @@ -676,10 +672,4 @@ public class NodeFactoryImpl extends NodeFactory { } } - public ConfigAttributes getConfigAttributes() { - return configAttributes; - } - public void setConfigAttributes(ConfigAttributes configAttributes) { - this.configAttributes = configAttributes; - } } diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java index aabb1c6abc..5a363e68af 100644 --- a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java +++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java @@ -45,6 +45,7 @@ import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.node.Client; import org.apache.tuscany.sca.node.Node; import org.apache.tuscany.sca.node.NodeFinder; @@ -52,6 +53,7 @@ import org.apache.tuscany.sca.node.configuration.NodeConfiguration; import org.apache.tuscany.sca.node.management.NodeManager; import org.apache.tuscany.sca.runtime.ActivationException; import org.apache.tuscany.sca.runtime.CompositeActivator; +import org.apache.tuscany.sca.runtime.DomainRegistryFactory; import org.apache.tuscany.sca.runtime.EndpointRegistry; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentContext; @@ -113,15 +115,20 @@ public class NodeImpl implements Node, Client { this.proxyFactory = manager.proxyFactory; UtilityExtensionPoint utilities = manager.extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); - // FIXME: Get the endpoint registry by the Node configuration - EndpointRegistry endpointRegistry = utilities.getUtility(EndpointRegistry.class); + DomainRegistryFactory domainRegistryFactory = utilities.getUtility(DomainRegistryFactory.class); + EndpointRegistry endpointRegistry = + domainRegistryFactory.getEndpointRegistry(configuration.getDomainRegistryURI(), configuration + .getDomainURI()); + this.compositeActivator = utilities.getUtility(CompositeActivator.class); try { - domainComposite = manager.configureNode(configuration, contributions); + Monitor monitor = manager.monitorFactory.createMonitor(); + monitor.reset(); + domainComposite = manager.configureNode(configuration, contributions, monitor); this.compositeContext = new CompositeContextImpl(manager.extensionPoints, endpointRegistry, domainComposite); // Activate the composite - compositeActivator.activate(domainComposite); + compositeActivator.activate(compositeContext, domainComposite); // Start the composite compositeActivator.start(compositeContext, domainComposite); diff --git a/java/sca/modules/pom.xml b/java/sca/modules/pom.xml index acd9c797a5..2110f6b8aa 100644 --- a/java/sca/modules/pom.xml +++ b/java/sca/modules/pom.xml @@ -68,7 +68,6 @@ databinding-json domain-node endpoint-tribes - endpoint-wrapper extensibility extensibility-equinox host-http -- cgit v1.2.3