diff options
Diffstat (limited to '')
11 files changed, 2057 insertions, 197 deletions
diff --git a/java/sca/itest/builder/src/test/java/org/apache/tuscany/sca/itest/builder/TestUtils.java b/java/sca/itest/builder/src/test/java/org/apache/tuscany/sca/itest/builder/TestUtils.java index f59470078e..c7f2dad2c4 100644 --- a/java/sca/itest/builder/src/test/java/org/apache/tuscany/sca/itest/builder/TestUtils.java +++ b/java/sca/itest/builder/src/test/java/org/apache/tuscany/sca/itest/builder/TestUtils.java @@ -259,7 +259,8 @@ public class TestUtils { if (endpointReference.getTargetName() != null){ buffer += indent + " Wired: " +"\n"; buffer += indent + " Target: " + endpointReference.getTargetName()+"\n"; - if (endpointReference.getTargetEndpoint() != null){ + if (endpointReference.getTargetEndpoint() != null && + endpointReference.getTargetEndpoint().isUnresolved() == false){ buffer += indent + " Binding: " + endpointReference.getBinding().getName() +"\n"; buffer += indent + " TargetEndpoint: " + endpointReference.getTargetEndpoint().getBinding().getName()+"\n"; } else { diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Endpoint2.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Endpoint2.java index 076ea74284..2fe3595292 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Endpoint2.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Endpoint2.java @@ -32,6 +32,14 @@ import org.apache.tuscany.sca.policy.PolicySubject; public interface Endpoint2 extends Base, PolicySubject, Cloneable { /** + * Supports endpoint cloning + * + * @return endpoint + * @throws CloneNotSupportedException + */ + Object clone() throws CloneNotSupportedException; + + /** * Get the component model object * * @return component @@ -72,25 +80,24 @@ public interface Endpoint2 extends Base, PolicySubject, Cloneable { * @param binding */ void setBinding(Binding binding); - - - - - // not sure these are required + /** * Returns the interface contract defining the interface * * @return the interface contract */ - // InterfaceContract getInterfaceContract(); + InterfaceContract getInterfaceContract(); /** * Sets the interface contract defining the interface * * @param interfaceContract the interface contract */ - // void setInterfaceContract(InterfaceContract interfaceContract); - + void setInterfaceContract(InterfaceContract interfaceContract); + + + // not sure these are required + /** * Returns the binding specific URI for this endpoint. * diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/EndpointReference2.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/EndpointReference2.java index a0cc427804..78cb2487d5 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/EndpointReference2.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/EndpointReference2.java @@ -31,6 +31,14 @@ import org.apache.tuscany.sca.policy.PolicySubject; public interface EndpointReference2 extends Base, PolicySubject, Cloneable { /** + * Supports endpoint reference cloning + * + * @return endpointReference + * @throws CloneNotSupportedException + */ + Object clone() throws CloneNotSupportedException; + + /** * Get the component model object * * @return component @@ -114,24 +122,24 @@ public interface EndpointReference2 extends Base, PolicySubject, Cloneable { */ void setTargetEndpoint(Endpoint2 targetEndpoint); - - - - // not sure the methods below are required - /** * Returns the interface contract defining the interface * * @return the interface contract */ - //InterfaceContract getInterfaceContract(); + InterfaceContract getInterfaceContract(); /** * Sets the interface contract defining the interface * * @param interfaceContract the interface contract */ - //void setInterfaceContract(InterfaceContract interfaceContract); + void setInterfaceContract(InterfaceContract interfaceContract); + + + // not sure the methods below are required + + /** * Returns the binding specific target URI for this endpoint reference. diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReference2Builder.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReference2Builder.java new file mode 100644 index 0000000000..bb130695e7 --- /dev/null +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReference2Builder.java @@ -0,0 +1,43 @@ +/* + * 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.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference2; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * 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 EndpointReference2Builder { + + /** + * Build an endpoint. + * + * @param endpoint + * @param monitor + */ + void build(EndpointReference2 endpointReference, Monitor monitor); + +} diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java index 3f184767c0..3fc0a0aa32 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java @@ -62,6 +62,7 @@ public class CompositeBuilderImpl implements CompositeBuilder { private CompositeBuilder compositeReferenceEndpointReferenceBuilder; private CompositeBuilder compositeServiceEndpointBuilder; + private CompositeBuilder endpointReferenceBuilder; public CompositeBuilderImpl(FactoryExtensionPoint factories, InterfaceContractMapper mapper) { this(factories.getFactory(AssemblyFactory.class), @@ -176,6 +177,7 @@ public class CompositeBuilderImpl implements CompositeBuilder { compositeReferenceEndpointReferenceBuilder = new CompositeReferenceEndpointReferenceBuilderImpl(assemblyFactory, interfaceContractMapper); compositeServiceEndpointBuilder = new CompositeServiceEndpointBuilderImpl(assemblyFactory); + endpointReferenceBuilder = new EndpointReference2BuilderImpl(assemblyFactory, interfaceContractMapper); } public String getID() { @@ -222,7 +224,12 @@ public class CompositeBuilderImpl implements CompositeBuilder { // create service endpoint models compositeServiceEndpointBuilder.build(composite, definitions, monitor); // create reference enpointreference models - compositeReferenceEndpointReferenceBuilder.build(composite, definitions, monitor); + compositeReferenceEndpointReferenceBuilder.build(composite, definitions, monitor); + + // TODO this needs to be offloaded to a plugpoint + // could be called upon when rebuilding wires + // wire endpoint references to endpoints + endpointReferenceBuilder.build(composite, definitions, monitor); // =============================================== // Wire the components diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeReferenceEndpointReferenceBuilderImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeReferenceEndpointReferenceBuilderImpl.java index 33867e0127..28afd1d177 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeReferenceEndpointReferenceBuilderImpl.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeReferenceEndpointReferenceBuilderImpl.java @@ -139,14 +139,20 @@ public class CompositeReferenceEndpointReferenceBuilderImpl extends BaseBuilderI if (reference.getInterfaceContract() == null || interfaceContractMapper.isCompatible(reference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { - + // create endpoint reference EndpointReference2 endpointRef = assemblyFactory.createEndpointReference(); endpointRef.setComponent(component); endpointRef.setReference(reference); endpointRef.setTargetName(targetComponentService.getName()); endpointRef.setUnresolved(false); - matchForwardBinding(endpointRef, targetComponentService, monitor); - matchCallbackBinding(endpointRef, targetComponentService, monitor); + + // create dummy endpoint. This will be replaced when policies + // are matched and bindings are configured later + Endpoint2 endpoint = assemblyFactory.createEndpoint(); + endpoint.setComponent(targetComponent); + endpoint.setService(targetComponentService); + endpoint.setUnresolved(true); + endpointRef.setTargetEndpoint(endpoint); reference.getEndpointReferences().add(endpointRef); @@ -201,13 +207,20 @@ public class CompositeReferenceEndpointReferenceBuilderImpl extends BaseBuilderI interfaceContractMapper.isCompatible(reference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { + // create endpoint reference EndpointReference2 endpointRef = assemblyFactory.createEndpointReference(); endpointRef.setComponent(component); endpointRef.setReference(reference); endpointRef.setTargetName(targetComponentService.getName()); endpointRef.setUnresolved(false); - matchForwardBinding(endpointRef, targetComponentService, monitor); - matchCallbackBinding(endpointRef, targetComponentService, monitor); + + // create dummy endpoint. This will be replaced when policies + // are matched and bindings are configured later + Endpoint2 endpoint = assemblyFactory.createEndpoint(); + endpoint.setComponent(targetComponent); + endpoint.setService(targetComponentService); + endpoint.setUnresolved(true); + endpointRef.setTargetEndpoint(endpoint); reference.getEndpointReferences().add(endpointRef); } else { @@ -219,7 +232,7 @@ public class CompositeReferenceEndpointReferenceBuilderImpl extends BaseBuilderI targetName); } } else { - // add an unresolved endpoint + // add an unresolved endpoint reference EndpointReference2 endpointRef = assemblyFactory.createEndpointReference(); endpointRef.setComponent(component); endpointRef.setReference(reference); @@ -259,13 +272,20 @@ public class CompositeReferenceEndpointReferenceBuilderImpl extends BaseBuilderI interfaceContractMapper.isCompatible(reference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { + // create endpoint reference EndpointReference2 endpointRef = assemblyFactory.createEndpointReference(); endpointRef.setComponent(component); endpointRef.setReference(reference); endpointRef.setTargetName(targetComponentService.getName()); endpointRef.setUnresolved(false); - matchForwardBinding(endpointRef, targetComponentService, monitor); - matchCallbackBinding(endpointRef, targetComponentService, monitor); + + // create dummy endpoint. This will be replaced when policies + // are matched and bindings are configured later + Endpoint2 endpoint = assemblyFactory.createEndpoint(); + endpoint.setComponent(targetComponent); + endpoint.setService(targetComponentService); + endpoint.setUnresolved(true); + endpointRef.setTargetEndpoint(endpoint); reference.getEndpointReferences().add(endpointRef); } else { @@ -277,7 +297,7 @@ public class CompositeReferenceEndpointReferenceBuilderImpl extends BaseBuilderI targetName); } } else { - // add an unresolved endpoint + // add an unresolved endpoint reference EndpointReference2 endpointRef = assemblyFactory.createEndpointReference(); endpointRef.setComponent(component); endpointRef.setReference(reference); @@ -349,14 +369,21 @@ public class CompositeReferenceEndpointReferenceBuilderImpl extends BaseBuilderI if (reference.getInterfaceContract() == null || interfaceContractMapper.isCompatible(reference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { + // create enpoint reference EndpointReference2 endpointRef = assemblyFactory.createEndpointReference(); endpointRef.setComponent(component); endpointRef.setReference(reference); endpointRef.setBinding(binding); endpointRef.setTargetName(targetComponentService.getName()); endpointRef.setUnresolved(false); - matchForwardBinding(endpointRef, targetComponentService, monitor); - matchCallbackBinding(endpointRef, targetComponentService, monitor); + + // create dummy endpoint. This will be replaced when policies + // are matched and bindings are configured later + Endpoint2 endpoint = assemblyFactory.createEndpoint(); + endpoint.setComponent(targetComponent); + endpoint.setService(targetComponentService); + endpoint.setUnresolved(true); + endpointRef.setTargetEndpoint(endpoint); reference.getEndpointReferences().add(endpointRef); } else { @@ -380,162 +407,5 @@ public class CompositeReferenceEndpointReferenceBuilderImpl extends BaseBuilderI } } } - } - - private void matchForwardBinding(EndpointReference2 endpointReference, - ComponentService service, - Monitor monitor) { - - List<Binding> matchedReferenceBinding = new ArrayList<Binding>(); - List<Endpoint2> matchedServiceEndpoint = new ArrayList<Endpoint2>(); - - // Find the corresponding bindings from the service side - for (Binding referenceBinding : endpointReference.getReference().getBindings()) { - for (Endpoint2 serviceEndpoint : service.getEndpoints()) { - - if (referenceBinding.getClass() == serviceEndpoint.getBinding().getClass() && - hasCompatiblePolicySets(referenceBinding, serviceEndpoint.getBinding())) { - - matchedReferenceBinding.add(referenceBinding); - matchedServiceEndpoint.add(serviceEndpoint); - } - } - } - - if (matchedReferenceBinding.isEmpty()) { - // No matching binding - endpointReference.setBinding(null); - endpointReference.setTargetEndpoint(null); - warning(monitor, - "NoMatchingBinding", - endpointReference.getReference(), - endpointReference.getReference().getName(), - service.getName()); - return; - } else { - // default to using the first matched binding - int selectedBinding = 0; - - for (int i = 0; i < matchedReferenceBinding.size(); i++) { - // If binding.sca is present, use it - if (SCABinding.class.isInstance(matchedReferenceBinding.get(i))) { - selectedBinding = i; - } - } - - Binding referenceBinding = matchedReferenceBinding.get(selectedBinding); - Endpoint2 serviceEndpoint = matchedServiceEndpoint.get(selectedBinding); - - // populate the endpoint reference - try { - - Binding cloned = (Binding) referenceBinding.clone(); - - // Set the binding URI to the URI of the target service - // that has been matched - if (referenceBinding.getURI() == null) { - cloned.setURI(serviceEndpoint.getBinding().getURI()); - } - - endpointReference.setBinding(referenceBinding); - endpointReference.setTargetEndpoint(serviceEndpoint); - - } catch (Exception ex) { - // do nothing - } - } - } - - // TODO - // Pretty much a duplicate of matchForwardBinding to handle callback bindings - // will rationalize when I understand what we need to do with callbacks - private void matchCallbackBinding(EndpointReference2 endpointReference, - ComponentService service, - Monitor monitor) { - - // if no callback on the interface do nothing - if (endpointReference.getReference().getInterfaceContract() == null || - endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null){ - return; - } - - List<Binding> matchedReferenceBinding = new ArrayList<Binding>(); - List<Binding> matchedServiceBinding = new ArrayList<Binding>(); - - // Find the corresponding bindings from the service side - for (Binding referenceBinding : endpointReference.getReference().getCallback().getBindings()) { - for (Binding serviceBinding : service.getCallback().getBindings()) { - - if (referenceBinding.getClass() == serviceBinding.getClass() && - hasCompatiblePolicySets(referenceBinding, serviceBinding)) { - - matchedReferenceBinding.add(referenceBinding); - matchedServiceBinding.add(serviceBinding); - } - } - } - - if (matchedReferenceBinding.isEmpty()) { - // No matching binding - endpointReference.setBinding(null); - endpointReference.setTargetEndpoint(null); - warning(monitor, - "NoMatchingCallbackBinding", - endpointReference.getReference(), - endpointReference.getReference().getName(), - service.getName()); - return; - } else { - // default to using the first matched binding - int selectedBinding = 0; - - for (int i = 0; i < matchedReferenceBinding.size(); i++){ - // If binding.sca is present, use it - if (SCABinding.class.isInstance(matchedReferenceBinding.get(i))) { - selectedBinding = i; - } - } - - Binding referenceBinding = matchedReferenceBinding.get(selectedBinding); - Binding serviceBinding = matchedServiceBinding.get(selectedBinding); - - // populate the endpoint reference - try { - - Binding cloned = (Binding)referenceBinding.clone(); - - // Set the binding URI to the URI of the target service - // that has been matched - if (referenceBinding.getURI() == null) { - cloned.setURI(serviceBinding.getURI()); - } - - endpointReference.setCallbackBinding(referenceBinding); - - } catch (Exception ex) { - // do nothing - } - } - } - - private boolean hasCompatiblePolicySets(Binding refBinding, Binding svcBinding) { - boolean isCompatible = true; - if ( refBinding instanceof PolicySubject && svcBinding instanceof PolicySubject ) { - //TODO : need to add more compatibility checks at the policy attachment levels - for ( PolicySet svcPolicySet : ((PolicySubject)svcBinding).getPolicySets() ) { - isCompatible = false; - for ( PolicySet refPolicySet : ((PolicySubject)refBinding).getPolicySets() ) { - if ( svcPolicySet.equals(refPolicySet) ) { - isCompatible = true; - break; - } - } - //if there exists no matching policy set in the reference binding - if ( !isCompatible ) { - return isCompatible; - } - } - } - return isCompatible; } } diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/EndpointReference2BuilderImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/EndpointReference2BuilderImpl.java new file mode 100644 index 0000000000..595333ca41 --- /dev/null +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/EndpointReference2BuilderImpl.java @@ -0,0 +1,320 @@ +/* + * 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.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.Endpoint2; +import org.apache.tuscany.sca.assembly.EndpointReference2; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.OptimizableBinding; +import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilder; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; +import org.apache.tuscany.sca.assembly.builder.EndpointBuilder; +import org.apache.tuscany.sca.assembly.builder.EndpointReference2Builder; +import org.apache.tuscany.sca.definitions.Definitions; +import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySubject; + +/** + * 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 EndpointReference2BuilderImpl extends BaseBuilderImpl implements CompositeBuilder, EndpointReference2Builder { + + + public EndpointReference2BuilderImpl(AssemblyFactory assemblyFactory, InterfaceContractMapper interfaceContractMapper) { + super(assemblyFactory, null, null, null, interfaceContractMapper); + } + + public String getID() { + return "org.apache.tuscany.sca.assembly.builder.EndpointReference2Builder"; + } + + /** + * Build all the endpoint references + * + * @param composite + */ + public void build(Composite composite, Definitions definitions, Monitor monitor) throws CompositeBuilderException + { + // process top level composite references + // TODO - I don't think OASIS allows for these + // + //processCompositeReferences(composite); + + // process component services + processComponentReferences(composite, monitor); + } + + private void processCompositeReferences(Composite composite) { + // TODO do we need this for OASIS? + } + + private void processComponentReferences(Composite composite, Monitor monitor) { + + // index all of the components in the composite + Map<String, Component> components = new HashMap<String, Component>(); + indexComponents(composite, components); + + // index all of the services in the composite + Map<String, ComponentService> componentServices = new HashMap<String, ComponentService>(); + indexServices(composite, componentServices); + + // create endpoint references for each component's references + for (Component component : composite.getComponents()) { + // recurse for composite implementations + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + processComponentReferences((Composite)implementation, monitor); + } + + // create endpoint references to represent the component reference + for (ComponentReference reference : component.getReferences()) { + for (EndpointReference2 endpointReference : reference.getEndpointReferences()){ + build(endpointReference, monitor); + } + } + } + } + + /** + * Build a single endpoint reference + * + * @param endpoint + * @param monitor + */ + public void build(EndpointReference2 endpointReference, Monitor monitor) { + Endpoint2 endpoint = endpointReference.getTargetEndpoint(); + + + // check if the endpoint was available locally + if (endpoint == null){ + if (endpointReference.isUnresolved() == false){ + // this is a non-wired endpoint reference + return; + } else { + // target service is available remotely + + // go look it up in the domain + } + } else { + // target service is available locally + + // check for wired reference that's already resolved + if (endpoint.isUnresolved() == false){ + return; + } + + // find the real endpoint for this reference by matching bindings + // and policy sets + matchForwardBinding(endpointReference, + endpointReference.getTargetEndpoint().getService(), + monitor); + + matchCallbackBinding(endpointReference, + endpointReference.getTargetEndpoint().getService(), + monitor); + } + + } + + // TODO - In OASIS case there are no bindings to match with on the + // reference side. This code will be factored out into a pluggable + // piece + private void matchForwardBinding(EndpointReference2 endpointReference, + ComponentService service, + Monitor monitor) { + + List<Binding> matchedReferenceBinding = new ArrayList<Binding>(); + List<Endpoint2> matchedServiceEndpoint = new ArrayList<Endpoint2>(); + + // Find the corresponding bindings from the service side + for (Binding referenceBinding : endpointReference.getReference().getBindings()) { + for (Endpoint2 serviceEndpoint : service.getEndpoints()) { + + if (referenceBinding.getClass() == serviceEndpoint.getBinding().getClass() && + hasCompatiblePolicySets(referenceBinding, serviceEndpoint.getBinding())) { + + matchedReferenceBinding.add(referenceBinding); + matchedServiceEndpoint.add(serviceEndpoint); + } + } + } + + if (matchedReferenceBinding.isEmpty()) { + // No matching binding + endpointReference.setBinding(null); + endpointReference.setTargetEndpoint(null); + warning(monitor, + "NoMatchingBinding", + endpointReference.getReference(), + endpointReference.getReference().getName(), + service.getName()); + return; + } else { + // default to using the first matched binding + int selectedBinding = 0; + + for (int i = 0; i < matchedReferenceBinding.size(); i++) { + // If binding.sca is present, use it + if (SCABinding.class.isInstance(matchedReferenceBinding.get(i))) { + selectedBinding = i; + } + } + + Binding referenceBinding = matchedReferenceBinding.get(selectedBinding); + Endpoint2 serviceEndpoint = matchedServiceEndpoint.get(selectedBinding); + + // populate the endpoint reference + try { + + Binding cloned = (Binding) referenceBinding.clone(); + + // Set the binding URI to the URI of the target service + // that has been matched + if (referenceBinding.getURI() == null) { + cloned.setURI(serviceEndpoint.getBinding().getURI()); + } + + endpointReference.setBinding(referenceBinding); + endpointReference.setTargetEndpoint(serviceEndpoint); + + } catch (Exception ex) { + // do nothing + } + } + } + + // TODO + // Pretty much a duplicate of matchForwardBinding to handle callback bindings + // will rationalize when I understand what we need to do with callbacks + private void matchCallbackBinding(EndpointReference2 endpointReference, + ComponentService service, + Monitor monitor) { + + // if no callback on the interface do nothing + if (endpointReference.getReference().getInterfaceContract() == null || + endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null){ + return; + } + + List<Binding> matchedReferenceBinding = new ArrayList<Binding>(); + List<Binding> matchedServiceBinding = new ArrayList<Binding>(); + + // Find the corresponding bindings from the service side + for (Binding referenceBinding : endpointReference.getReference().getCallback().getBindings()) { + for (Binding serviceBinding : service.getCallback().getBindings()) { + + if (referenceBinding.getClass() == serviceBinding.getClass() && + hasCompatiblePolicySets(referenceBinding, serviceBinding)) { + + matchedReferenceBinding.add(referenceBinding); + matchedServiceBinding.add(serviceBinding); + } + } + } + + if (matchedReferenceBinding.isEmpty()) { + // No matching binding + endpointReference.setBinding(null); + endpointReference.setTargetEndpoint(null); + warning(monitor, + "NoMatchingCallbackBinding", + endpointReference.getReference(), + endpointReference.getReference().getName(), + service.getName()); + return; + } else { + // default to using the first matched binding + int selectedBinding = 0; + + for (int i = 0; i < matchedReferenceBinding.size(); i++){ + // If binding.sca is present, use it + if (SCABinding.class.isInstance(matchedReferenceBinding.get(i))) { + selectedBinding = i; + } + } + + Binding referenceBinding = matchedReferenceBinding.get(selectedBinding); + Binding serviceBinding = matchedServiceBinding.get(selectedBinding); + + // populate the endpoint reference + try { + + Binding cloned = (Binding)referenceBinding.clone(); + + // Set the binding URI to the URI of the target service + // that has been matched + if (referenceBinding.getURI() == null) { + cloned.setURI(serviceBinding.getURI()); + } + + endpointReference.setCallbackBinding(referenceBinding); + + } catch (Exception ex) { + // do nothing + } + } + } + + private boolean hasCompatiblePolicySets(Binding refBinding, Binding svcBinding) { + boolean isCompatible = true; + if ( refBinding instanceof PolicySubject && svcBinding instanceof PolicySubject ) { + //TODO : need to add more compatibility checks at the policy attachment levels + for ( PolicySet svcPolicySet : ((PolicySubject)svcBinding).getPolicySets() ) { + isCompatible = false; + for ( PolicySet refPolicySet : ((PolicySubject)refBinding).getPolicySets() ) { + if ( svcPolicySet.equals(refPolicySet) ) { + isCompatible = true; + break; + } + } + //if there exists no matching policy set in the reference binding + if ( !isCompatible ) { + return isCompatible; + } + } + } + return isCompatible; + } + +} diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/Endpoint2Impl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/Endpoint2Impl.java index 94309b6641..67041fc66a 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/Endpoint2Impl.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/Endpoint2Impl.java @@ -38,11 +38,12 @@ import org.apache.tuscany.sca.policy.PolicySubject; */ public class Endpoint2Impl implements Endpoint2 { + private Boolean unresolved; private Component component; private ComponentService service; private Binding binding; private Binding callbackBinding; - //private InterfaceContract interfaceContract; + private InterfaceContract interfaceContract; //private String uri; private List<PolicySet> policySets = new ArrayList<PolicySet>(); private List<Intent> requiredIntents = new ArrayList<Intent>(); @@ -56,12 +57,11 @@ public class Endpoint2Impl implements Endpoint2 { } public boolean isUnresolved() { - // TODO Auto-generated method stub - return false; + return unresolved; } public void setUnresolved(boolean unresolved) { - // TODO Auto-generated method stub + this.unresolved = unresolved; } public Component getComponent() { @@ -87,7 +87,7 @@ public class Endpoint2Impl implements Endpoint2 { public void setBinding(Binding binding) { this.binding = binding; } -/* + public InterfaceContract getInterfaceContract() { return interfaceContract; } @@ -95,7 +95,7 @@ public class Endpoint2Impl implements Endpoint2 { public void setInterfaceContract(InterfaceContract interfaceContract) { this.interfaceContract = interfaceContract; } - +/* public String getURI() { return uri; } diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReference2Impl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReference2Impl.java index eacdeb4cad..f59bf519f4 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReference2Impl.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/EndpointReference2Impl.java @@ -39,6 +39,7 @@ import org.apache.tuscany.sca.policy.PolicySubject; */ public class EndpointReference2Impl implements EndpointReference2 { + private Boolean unresolved = true; private Component component; private ComponentReference reference; private Binding binding; @@ -46,7 +47,7 @@ public class EndpointReference2Impl implements EndpointReference2 { private String targetName; private Endpoint2 targetEndpoint; private InterfaceContract interfaceContract; - private String uri; +// private String uri; private List<PolicySet> policySets = new ArrayList<PolicySet>(); private List<Intent> requiredIntents = new ArrayList<Intent>(); @@ -59,12 +60,11 @@ public class EndpointReference2Impl implements EndpointReference2 { } public boolean isUnresolved() { - // TODO Auto-generated method stub - return false; + return unresolved; } public void setUnresolved(boolean unresolved) { - // TODO Auto-generated method stub + this.unresolved = unresolved; } public Component getComponent() { @@ -116,7 +116,7 @@ public class EndpointReference2Impl implements EndpointReference2 { } - /* + public InterfaceContract getInterfaceContract() { return interfaceContract; } @@ -124,7 +124,8 @@ public class EndpointReference2Impl implements EndpointReference2 { public void setInterfaceContract(InterfaceContract interfaceContract) { this.interfaceContract = interfaceContract; } - + + /* public String getURI() { return uri; } diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl2.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl2.java new file mode 100644 index 0000000000..a1c99c97fc --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl2.java @@ -0,0 +1,1118 @@ +/* + * 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.security.AccessController; +import java.security.PrivilegedAction; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.Endpoint2; +import org.apache.tuscany.sca.assembly.EndpointReference2; +import org.apache.tuscany.sca.assembly.Implementation; +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.context.ComponentContextFactory; +import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint; +import org.apache.tuscany.sca.context.PropertyValueFactory; +import org.apache.tuscany.sca.context.RequestContextFactory; +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.assembly.ActivationException; +import org.apache.tuscany.sca.core.assembly.CompositeActivator; +import org.apache.tuscany.sca.core.context.CompositeContext; +import org.apache.tuscany.sca.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.sca.core.conversation.ConversationManager; +import org.apache.tuscany.sca.core.invocation.ExtensibleWireProcessor; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.core.scope.Scope; +import org.apache.tuscany.sca.core.scope.ScopeContainer; +import org.apache.tuscany.sca.core.scope.ScopeRegistry; +import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent; +import org.apache.tuscany.sca.core.scope.impl.ConversationalScopeContainer; +import org.apache.tuscany.sca.endpointresolver.EndpointResolver; +import org.apache.tuscany.sca.endpointresolver.EndpointResolverFactory; +import org.apache.tuscany.sca.endpointresolver.EndpointResolverFactoryExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.provider.BindingProviderFactory; +import org.apache.tuscany.sca.provider.ImplementationProvider; +import org.apache.tuscany.sca.provider.ImplementationProviderFactory; +import org.apache.tuscany.sca.provider.PolicyProvider; +import org.apache.tuscany.sca.provider.PolicyProviderFactory; +import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint; +import org.apache.tuscany.sca.provider.ReferenceBindingProvider; +import org.apache.tuscany.sca.provider.ServiceBindingProvider; +import org.apache.tuscany.sca.runtime.EndpointReference; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentContext; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; +import org.apache.tuscany.sca.runtime.RuntimeWire; +import org.apache.tuscany.sca.runtime.RuntimeWireProcessor; +import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint; +import org.apache.tuscany.sca.work.WorkScheduler; + +/** + * @version $Rev$ $Date$ + */ +public class CompositeActivatorImpl2 implements CompositeActivator { + private static final Logger logger = Logger.getLogger(CompositeActivatorImpl2.class.getName()); + + private final AssemblyFactory assemblyFactory; + private final MessageFactory messageFactory; + private final InterfaceContractMapper interfaceContractMapper; + private final ScopeRegistry scopeRegistry; + private final WorkScheduler workScheduler; + private final RuntimeWireProcessor wireProcessor; + private final ProviderFactoryExtensionPoint providerFactories; + private final EndpointResolverFactoryExtensionPoint endpointResolverFactories; + + private final ComponentContextFactory componentContextFactory; + private final RequestContextFactory requestContextFactory; + private final ProxyFactory proxyFactory; + private final JavaInterfaceFactory javaInterfaceFactory; + private final PropertyValueFactory propertyValueFactory; + + private final ConversationManager conversationManager; + + private final CompositeContext compositeContext; + + private Composite domainComposite; + + public CompositeActivatorImpl2(ExtensionPointRegistry extensionPoints) { + this.compositeContext = new CompositeContextImpl(extensionPoints); + FactoryExtensionPoint factories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + this.assemblyFactory = factories.getFactory(AssemblyFactory.class); + this.messageFactory = factories.getFactory(MessageFactory.class); + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + this.interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class); + this.scopeRegistry = utilities.getUtility(ScopeRegistry.class); + this.workScheduler = utilities.getUtility(WorkScheduler.class); + this.wireProcessor = new ExtensibleWireProcessor(extensionPoints.getExtensionPoint(RuntimeWireProcessorExtensionPoint.class)); + this.providerFactories = extensionPoints.getExtensionPoint(ProviderFactoryExtensionPoint.class); + this.endpointResolverFactories = extensionPoints.getExtensionPoint(EndpointResolverFactoryExtensionPoint.class); + this.javaInterfaceFactory = compositeContext.getJavaInterfaceFactory(); + this.propertyValueFactory = factories.getFactory(PropertyValueFactory.class); + ContextFactoryExtensionPoint contextFactories = extensionPoints.getExtensionPoint(ContextFactoryExtensionPoint.class); + this.componentContextFactory = contextFactories.getFactory(ComponentContextFactory.class); + this.requestContextFactory = contextFactories.getFactory(RequestContextFactory.class); + proxyFactory = compositeContext.getProxyFactory(); + this.conversationManager = compositeContext.getConversationManager(); + } + + //========================================================================= + // Activation + //========================================================================= + + // Composite activation/deactivation + + public void activate(Composite composite) throws ActivationException { + try { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Activating composite: " + composite.getName()); + } + for (Component component : composite.getComponents()) { + activateComponent(component); + } + } catch (Exception e) { + throw new ActivationException(e); + } + } + + public void deactivate(Composite composite) throws ActivationException { + try { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Deactivating composite: " + composite.getName()); + } + for (Component component : composite.getComponents()) { + deactivateComponent(component); + } + } catch (Exception e) { + throw new ActivationException(e); + } + } + + // Component activation/deactivation + + public void activateComponent(Component component) + throws ActivationException { + try { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Activating component: " + component.getURI()); + } + + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + activate((Composite) implementation); + } else if (implementation != null) { + addImplementationProvider((RuntimeComponent) component, + implementation); + addScopeContainer(component); + } + + for (ComponentService service : component.getServices()) { + activate((RuntimeComponent) component, + (RuntimeComponentService) service); + } + + for (ComponentReference reference : component.getReferences()) { + activate((RuntimeComponent) component, + (RuntimeComponentReference) reference); + } + } catch (Exception e) { + throw new ActivationException(e); + } + } + + public void deactivateComponent(Component component) + throws ActivationException { + try { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Deactivating component: " + component.getURI()); + } + for (ComponentService service : component.getServices()) { + deactivate((RuntimeComponent) component, + (RuntimeComponentService) service); + } + + for (ComponentReference reference : component.getReferences()) { + deactivate((RuntimeComponent) component, + (RuntimeComponentReference) reference); + } + + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + deactivate((Composite) implementation); + } else if (implementation != null) { + removeImplementationProvider((RuntimeComponent) component); + removeScopeContainer(component); + } + } catch (Exception e) { + throw new ActivationException(e); + } + } + + // add/remove artifacts required to get the implementation going + + private void addImplementationProvider(RuntimeComponent component, Implementation implementation) { + ImplementationProviderFactory providerFactory = + (ImplementationProviderFactory)providerFactories.getProviderFactory(implementation.getClass()); + if (providerFactory != null) { + @SuppressWarnings("unchecked") + ImplementationProvider implementationProvider = + providerFactory.createImplementationProvider(component, implementation); + if (implementationProvider != null) { + component.setImplementationProvider(implementationProvider); + } + } else { + throw new IllegalStateException("Provider factory not found for class: " + implementation.getClass() + .getName()); + } + for (PolicyProviderFactory f : providerFactories.getPolicyProviderFactories()) { + PolicyProvider policyProvider = f.createImplementationPolicyProvider(component, implementation); + if (policyProvider != null) { + component.addPolicyProvider(policyProvider); + } + } + + } + + private void removeImplementationProvider(RuntimeComponent component) { + component.setImplementationProvider(null); + component.getPolicyProviders().clear(); + } + + private void addScopeContainer(Component component) { + if (!(component instanceof ScopedRuntimeComponent)) { + return; + } + ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component; + ScopeContainer scopeContainer = scopeRegistry.getScopeContainer(runtimeComponent); + if (scopeContainer != null && scopeContainer.getScope() == Scope.CONVERSATION) { + conversationManager.addListener((ConversationalScopeContainer)scopeContainer); + } + runtimeComponent.setScopeContainer(scopeContainer); + } + + private void removeScopeContainer(Component component) { + if (!(component instanceof ScopedRuntimeComponent)) { + return; + } + ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component; + ScopeContainer scopeContainer = runtimeComponent.getScopeContainer(); + if(scopeContainer != null && scopeContainer.getScope() == Scope.CONVERSATION) { + conversationManager.removeListener((ConversationalScopeContainer) scopeContainer); + } + runtimeComponent.setScopeContainer(null); + } + + + // Service activation/deactivation + + public void activate(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() + + "#" + + service.getName()); + } + return; + } + if (service.getService() instanceof CompositeService) { + return; + } + if (logger.isLoggable(Level.FINE)) { + logger.fine("Activating component service: " + component.getURI() + "#" + service.getName()); + } + + for (Binding binding : service.getBindings()) { + addServiceBindingProvider(component, service, binding); + } + addServiceWires(component, service); + } + + public void deactivate(RuntimeComponent component, RuntimeComponentService service) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Deactivating component service: " + component.getURI() + "#" + service.getName()); + } + removeServiceWires(service); + for (Binding binding : service.getBindings()) { + removeServiceBindingProvider(component, service, binding); + } + } + + private ServiceBindingProvider addServiceBindingProvider( + RuntimeComponent component, RuntimeComponentService service, + Binding binding) { + BindingProviderFactory providerFactory = (BindingProviderFactory) providerFactories + .getProviderFactory(binding.getClass()); + if (providerFactory != null) { + @SuppressWarnings("unchecked") + ServiceBindingProvider bindingProvider = providerFactory + .createServiceBindingProvider((RuntimeComponent) component, + (RuntimeComponentService) service, binding); + if (bindingProvider != null) { + ((RuntimeComponentService) service).setBindingProvider(binding, + bindingProvider); + } + for (PolicyProviderFactory f : providerFactories + .getPolicyProviderFactories()) { + PolicyProvider policyProvider = f.createServicePolicyProvider( + component, service, binding); + if (policyProvider != null) { + service.addPolicyProvider(binding, policyProvider); + } + } + return bindingProvider; + } else { + throw new IllegalStateException( + "Provider factory not found for class: " + + binding.getClass().getName()); + } + } + + private void removeServiceBindingProvider(RuntimeComponent component, + RuntimeComponentService service, Binding binding) { + service.setBindingProvider(binding, null); + for (Binding b : service.getBindings()) { + List<PolicyProvider> pps = service.getPolicyProviders(b); + if (pps != null) { + pps.clear(); + } + } + } + + private void addServiceWires(Component serviceComponent, ComponentService service) { + if (!(service instanceof RuntimeComponentService)) { + return; + } + + RuntimeComponentService runtimeService = (RuntimeComponentService)service; + + // Add a wire for each service Endpoint + for ( Endpoint2 endpoint : runtimeService.getEndpoints()){ + + // fluff up a fake endpoint reference as we are on the service side + // so we need to represent the reference that will call us + EndpointReference2 endpointReference = assemblyFactory.createEndpointReference(); + endpointReference.setBinding(endpoint.getBinding()); + + // create the interface contract for the binding and service ends of the wire + // that are created as forward only contracts + // FIXME: [rfeng] We might need a better way to get the impl interface contract + Service targetService = service.getService(); + if (targetService == null) { + targetService = service; + } + endpoint.setInterfaceContract(targetService.getInterfaceContract().makeUnidirectional(false)); + endpointReference.setInterfaceContract(getServiceBindingInterfaceContract(service, endpoint.getBinding())); + + // create the wire + RuntimeWire wire = new RuntimeWireImpl2(false, + endpointReference, + endpoint, + interfaceContractMapper, + workScheduler, + wireProcessor, + messageFactory, + conversationManager); + + runtimeService.getRuntimeWires().add(wire); + } + } + + private void removeServiceWires(ComponentService service) { + if (!(service instanceof RuntimeComponentService)) { + return; + } + RuntimeComponentService runtimeService = (RuntimeComponentService)service; + runtimeService.getRuntimeWires().clear(); + } + + private InterfaceContract getServiceBindingInterfaceContract(ComponentService service, Binding binding) { + InterfaceContract interfaceContract = service.getInterfaceContract(); + + ServiceBindingProvider provider = ((RuntimeComponentService)service).getBindingProvider(binding); + if (provider != null) { + InterfaceContract bindingContract = provider.getBindingInterfaceContract(); + if (bindingContract != null) { + interfaceContract = bindingContract; + } + } + return interfaceContract.makeUnidirectional(false); + } + + // Reference activation/deactivation + + public void activate(RuntimeComponent component, RuntimeComponentReference ref) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Activating component reference: " + component.getURI() + "#" + ref.getName()); + } + resolveTargets(ref); + for (Binding binding : ref.getBindings()) { + addReferenceBindingProvider(component, ref, binding); + } + + for (Endpoint endpoint : ref.getEndpoints()){ + // TODO - source component should be set in the builder but the + // way the builder is written it's difficult to get at it + endpoint.setSourceComponent(component); + + addEndpointResolver(component, ref, endpoint); + } + } + + public void deactivate(RuntimeComponent component, RuntimeComponentReference ref) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Deactivating component reference: " + component.getURI() + "#" + ref.getName()); + } + removeReferenceWires(ref); + for (Binding binding : ref.getBindings()) { + removeReferenceBindingProvider(component, ref, binding); + } + + } + + private ReferenceBindingProvider addReferenceBindingProvider( + RuntimeComponent component, RuntimeComponentReference reference, + Binding binding) { + BindingProviderFactory providerFactory = (BindingProviderFactory) providerFactories + .getProviderFactory(binding.getClass()); + if (providerFactory != null) { + @SuppressWarnings("unchecked") + ReferenceBindingProvider bindingProvider = providerFactory + .createReferenceBindingProvider( + (RuntimeComponent) component, + (RuntimeComponentReference) reference, binding); + if (bindingProvider != null) { + ((RuntimeComponentReference) reference).setBindingProvider( + binding, bindingProvider); + } + for (PolicyProviderFactory f : providerFactories + .getPolicyProviderFactories()) { + PolicyProvider policyProvider = f + .createReferencePolicyProvider(component, reference, + binding); + if (policyProvider != null) { + reference.addPolicyProvider(binding, policyProvider); + } + } + + return bindingProvider; + } else { + throw new IllegalStateException( + "Provider factory not found for class: " + + binding.getClass().getName()); + } + } + + private void removeReferenceBindingProvider(RuntimeComponent component, + RuntimeComponentReference reference, Binding binding) { + reference.setBindingProvider(binding, null); + for (Binding b : reference.getBindings()) { + List<PolicyProvider> pps = reference.getPolicyProviders(b); + if (pps != null) { + pps.clear(); + } + } + } + + //========================================================================= + // Start + //========================================================================= + + // Composite start/stop + + public void start(Composite composite) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Starting composite: " + composite.getName()); + } + for (Component component : composite.getComponents()) { + start(component); + } + } + + public void stop(Composite composite) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Stopping composite: " + composite.getName()); + } + for (final Component component : composite.getComponents()) { + stop(component); + } + } + + // Component start/stop + + public void start(Component component) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Starting component: " + component.getURI()); + } + RuntimeComponent runtimeComponent = ((RuntimeComponent)component); + if(runtimeComponent.isStarted()) { + return; + } + + configureComponentContext(runtimeComponent); + + for (ComponentReference reference : component.getReferences()) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Starting component reference: " + component.getURI() + "#" + reference.getName()); + } + RuntimeComponentReference runtimeRef = ((RuntimeComponentReference)reference); + runtimeRef.setComponent(runtimeComponent); + + for (Endpoint endpoint : reference.getEndpoints()) { + final EndpointResolver endpointResolver = runtimeRef.getEndpointResolver(endpoint); + if (endpointResolver != null) { + // Allow endpoint resolvers to do any startup reference manipulation + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + endpointResolver.start(); + return null; + } + }); + } + } + + for (Binding binding : reference.getBindings()) { + final ReferenceBindingProvider bindingProvider = runtimeRef.getBindingProvider(binding); + if (bindingProvider != null) { + // Allow bindings to add shutdown hooks. Requires RuntimePermission shutdownHooks in policy. + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + bindingProvider.start(); + return null; + } + }); + } + } + } + + for (ComponentService service : component.getServices()) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Starting component service: " + component.getURI() + "#" + service.getName()); + } + RuntimeComponentService runtimeService = (RuntimeComponentService)service; + for (Binding binding : service.getBindings()) { + final ServiceBindingProvider bindingProvider = runtimeService.getBindingProvider(binding); + if (bindingProvider != null) { + // bindingProvider.start(); + // Allow bindings to add shutdown hooks. Requires RuntimePermission shutdownHooks in policy. + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + bindingProvider.start(); + return null; + } + }); + } + } + } + + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + start((Composite)implementation); + } else { + ImplementationProvider implementationProvider = runtimeComponent.getImplementationProvider(); + if (implementationProvider != null) { + implementationProvider.start(); + } + } + + if (component instanceof ScopedRuntimeComponent) { + ScopedRuntimeComponent scopedRuntimeComponent = (ScopedRuntimeComponent)component; + if (scopedRuntimeComponent.getScopeContainer() != null) { + scopedRuntimeComponent.getScopeContainer().start(); + } + } + + runtimeComponent.setStarted(true); + } + + public void stop(Component component) { + if (!((RuntimeComponent)component).isStarted()) { + return; + } + if (logger.isLoggable(Level.FINE)) { + logger.fine("Stopping component: " + component.getURI()); + } + for (ComponentService service : component.getServices()) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Stopping component service: " + component.getURI() + "#" + service.getName()); + } + for (Binding binding : service.getBindings()) { + final ServiceBindingProvider bindingProvider = ((RuntimeComponentService)service).getBindingProvider(binding); + if (bindingProvider != null) { + // Allow bindings to read properties. Requires PropertyPermission read in security policy. + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + bindingProvider.stop(); + return null; + } + }); + } + } + } + for (ComponentReference reference : component.getReferences()) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Starting component reference: " + component.getURI() + "#" + reference.getName()); + } + RuntimeComponentReference runtimeRef = ((RuntimeComponentReference)reference); + + for (Binding binding : reference.getBindings()) { + final ReferenceBindingProvider bindingProvider = runtimeRef.getBindingProvider(binding); + if (bindingProvider != null) { + // Allow bindings to read properties. Requires PropertyPermission read in security policy. + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + bindingProvider.stop(); + return null; + } + }); + } + } + + for (Endpoint endpoint : reference.getEndpoints()) { + final EndpointResolver endpointResolver = runtimeRef.getEndpointResolver(endpoint); + if (endpointResolver != null) { + // Allow endpoint resolvers to do any shutdown reference manipulation + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + endpointResolver.stop(); + return null; + } + }); + } + } + } + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + stop((Composite)implementation); + } else { + final ImplementationProvider implementationProvider = ((RuntimeComponent)component).getImplementationProvider(); + if (implementationProvider != null) { + // Allow bindings to read properties. Requires PropertyPermission read in security policy. + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + implementationProvider.stop(); + return null; + } + }); + } + } + + if (component instanceof ScopedRuntimeComponent) { + ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component; + if (runtimeComponent.getScopeContainer() != null && + runtimeComponent.getScopeContainer().getLifecycleState() != ScopeContainer.STOPPED) { + runtimeComponent.getScopeContainer().stop(); + } + } + + ((RuntimeComponent)component).setStarted(false); + } + + // Service start/stop + + // ???? + + // Reference start/stop + // Used by component context? + + public void start(RuntimeComponent component, RuntimeComponentReference ref) { + synchronized (ref) { + resolveTargets(ref); + for (Binding binding : ref.getBindings()) { + ReferenceBindingProvider provider = ref.getBindingProvider(binding); + if (provider == null) { + provider = addReferenceBindingProvider(component, ref, binding); + } + if (provider != null) { + provider.start(); + } + addReferenceWire(component, ref, binding); + } + + // targets now have an endpoint representation. We can use this to + // look for unresolved endpoints using dummy wires for late resolution + for (Endpoint endpoint : ref.getEndpoints()){ + addReferenceEndpointWire(component, ref, endpoint); + } + } + } + + public void stop(Component component, ComponentReference reference) { + if (logger.isLoggable(Level.FINE)) { + logger.fine("Stopping component reference: " + component.getURI() + "#" + reference.getName()); + } + RuntimeComponentReference runtimeRef = ((RuntimeComponentReference)reference); + for (Binding binding : reference.getBindings()) { + ReferenceBindingProvider bindingProvider = runtimeRef.getBindingProvider(binding); + if (bindingProvider != null) { + bindingProvider.stop(); + } + } + } + + + + + + + + //======================================================== + //======================================================== + //======================================================== + //======================================================== + + + + + + + + /** + * @param component + * @param reference + * @param binding + */ + private EndpointResolver addEndpointResolver(RuntimeComponent component, + RuntimeComponentReference reference, + Endpoint endpoint){ + + // only create endpoint resolvers for unresolved endpoints currently + // this will also prevent a wire from being created later + if (!endpoint.isUnresolved()){ + return null; + } + + // This souldn't happen as the endpoint resolver extension point is in core-spi but + // just in case returning null here will mean that no wire is created and calling + // the reference will fail with NPE + if (endpointResolverFactories == null){ + return null; + } + + EndpointResolverFactory<Endpoint> resolverFactory = + (EndpointResolverFactory<Endpoint>)endpointResolverFactories.getEndpointResolverFactory(endpoint.getClass()); + + if (resolverFactory != null) { + EndpointResolver endpointResolver = + resolverFactory.createEndpointResolver(endpoint, null); + if (endpointResolver != null) { + ((RuntimeComponentReference)reference).setEndpointResolver(endpoint, endpointResolver); + } + + return endpointResolver; + } else { + // TODO - for the time being allow the lack of an endpoint provider to be the + // switch to turn off endpoint processing + return null; + //throw new IllegalStateException("Endpoint provider factory not found for class: " + endpoint.getClass().getName()); + } + } + + public void addReferenceBindingProviderForEndpoint(Endpoint endpoint){ + addReferenceBindingProvider((RuntimeComponent)endpoint.getSourceComponent(), + (RuntimeComponentReference)endpoint.getSourceComponentReference(), + endpoint.getSourceBinding()); + } + + /** + * @param component + * @param reference + * @param binding + */ + + + /** + * @param reference + */ + private void resolveTargets(RuntimeComponentReference reference) { + // The code that used to be here to resolved unresolved targets is now + // at the bottom of BaseWireBuilder.connectComponentReferences() + } + + /** + * Create the runtime wires for a reference endpoint. Currently this method + * only deals with the late binding case and creates a dummy wire that + * will use the Endpoint to resolve the target at the point when the + * wire chains are created. + * + * @param component + * @param reference + * @param binding + */ + private void addReferenceEndpointWire(Component component, ComponentReference reference, Endpoint endpoint) { + // only deal with unresolved endpoints as, to prevent breaking changes, targets that are resolved + // at build time are still represented as bindings in the binding list + if (((RuntimeComponentReference)reference).getEndpointResolver(endpoint) == null){ + // no endpoint provider has previously been created so don't create the + // wire + return; + } + + // TODO: TUSCANY-2580: avoid NPE if the InterfaceCOntract is null + Reference ctref = endpoint.getSourceComponentReference().getReference(); + if (ctref != null && ctref.getInterfaceContract() == null) { + ctref.setInterfaceContract(reference.getInterfaceContract()); + } + + RuntimeWire wire = new EndpointWireImpl(endpoint, this); + + RuntimeComponentReference runtimeRef = (RuntimeComponentReference)reference; + runtimeRef.getRuntimeWires().add(wire); + } + + + /** + * Create the runtime wires for a reference binding + * + * @param component + * @param reference + * @param binding + */ + private void addReferenceWire(Component component, ComponentReference reference, Binding binding) { + if (!(reference instanceof RuntimeComponentReference)) { + return; + } + + // create wire if binding has an endpoint + Component targetComponent = null; + ComponentService targetComponentService = null; + Binding targetBinding = null; + + if (binding instanceof OptimizableBinding) { + OptimizableBinding endpoint = (OptimizableBinding)binding; + targetComponent = endpoint.getTargetComponent(); + targetComponentService = endpoint.getTargetComponentService(); + targetBinding = endpoint.getTargetBinding(); + // FIXME: TUSCANY-2136, For unresolved binding, don't add wire. Is it the right solution? + if (!reference.isCallback() && binding.getURI() == null && targetComponentService == null) { + return; + } + } + + // create a forward wire, either static or dynamic + addReferenceWire(component, reference, binding, targetComponent, targetComponentService, targetBinding); + + /* + // if static forward wire (not from self-reference), try to create a static callback wire + if (targetComponentService != null && !reference.getName().startsWith("$self$.")) { + ComponentReference callbackReference = targetComponentService.getCallbackReference(); + if (callbackReference != null) { + Binding callbackBinding = null; + Binding callbackServiceBinding = null; + // select a service callback binding that can be wired back to this component + for (Binding refBinding : callbackReference.getBindings()) { + // first look for a callback binding whose name matches the target binding name + if (refBinding.getName().equals(targetBinding.getName())) { + callbackBinding = refBinding; + break; + } + } + // see if there is a matching reference callback binding + if (callbackBinding != null) { + callbackServiceBinding = reference.getCallbackService().getBinding(callbackBinding.getClass()); + } + // if there isn't an end-to-end match, try again based on target binding type + if (callbackBinding == null || callbackServiceBinding == null) { + callbackBinding = callbackReference.getBinding(targetBinding.getClass()); + if (callbackBinding != null) { + callbackServiceBinding = reference.getCallbackService().getBinding(callbackBinding.getClass()); + } + } + if (callbackBinding != null && callbackServiceBinding != null) { + // end-to-end match, so create a static callback wire as well as the static forward wire + + addReferenceWire(targetComponent, callbackReference, callbackBinding, component, reference + .getCallbackService(), callbackServiceBinding); + } else { + // no end-to-end match, so do not create a static callback wire + } + } + } + */ + } + + public void addReferenceWireForEndpoint(Endpoint endpoint){ + addReferenceWire(endpoint.getSourceComponent(), + endpoint.getSourceComponentReference(), + endpoint.getSourceBinding(), + endpoint.getTargetComponent(), + endpoint.getTargetComponentService(), + endpoint.getTargetBinding()); + } + /** + * Create a reference wire for a forward call or a callback + * @param reference + * @param service + * @param serviceBinding + * @param component + * @param referenceBinding + */ + private RuntimeWire addReferenceWire(Component refComponent, + ComponentReference reference, + Binding refBinding, + Component serviceComponent, + ComponentService service, + Binding serviceBinding) { + RuntimeComponentReference runtimeRef = (RuntimeComponentReference)reference; + InterfaceContract bindingContract = getInterfaceContract(reference, refBinding); + + // Use the interface contract of the reference on the component type + Reference componentTypeRef = reference.getReference(); + + InterfaceContract sourceContract; + if (componentTypeRef == null || componentTypeRef.getInterfaceContract() == null) { + sourceContract = reference.getInterfaceContract(); + } else { + sourceContract = componentTypeRef.getInterfaceContract(); + } + + sourceContract = sourceContract.makeUnidirectional(false); + + EndpointReference wireSource = + new EndpointReferenceImpl((RuntimeComponent)refComponent, reference, refBinding, sourceContract); + ComponentService callbackService = reference.getCallbackService(); + if (callbackService != null) { + // select a reference callback binding to pass with invocations on this wire + Binding callbackBinding = null; + for (Binding binding : callbackService.getBindings()) { + // first look for a callback binding whose name matches the reference binding name + if (refBinding.getName().startsWith(binding.getName())) { + callbackBinding = binding; + break; + } + } + // if no callback binding found, try again based on reference binding type + if (callbackBinding == null) { + callbackBinding = callbackService.getBinding(refBinding.getClass()); + } + InterfaceContract callbackContract = callbackService.getInterfaceContract(); + EndpointReference callbackEndpoint = + new EndpointReferenceImpl((RuntimeComponent)refComponent, callbackService, callbackBinding, + callbackContract); + wireSource.setCallbackEndpoint(callbackEndpoint); + } + + EndpointReference wireTarget = + new EndpointReferenceImpl((RuntimeComponent)serviceComponent, service, serviceBinding, bindingContract); + + // TUSCANY-2029 - We should use the URI of the serviceBinding because the target may be a Component in a + // nested composite. + if (serviceBinding != null) { + wireTarget.setURI(serviceBinding.getURI()); + } + + RuntimeWire wire = + new RuntimeWireImpl(wireSource, wireTarget, interfaceContractMapper, workScheduler, wireProcessor, + messageFactory, conversationManager); + runtimeRef.getRuntimeWires().add(wire); + + return wire; + } + + + + /** + * @param component + * @param service + * @param binding + */ + + + + + + + + + /** + * @param runtimeComponent + */ + public void configureComponentContext(RuntimeComponent runtimeComponent) { + RuntimeComponentContext componentContext = (RuntimeComponentContext) componentContextFactory.createComponentContext(runtimeComponent); + runtimeComponent.setComponentContext(componentContext); + } + + /** + * Stop a component + */ + + + /** + * Get the effective interface contract for a reference binding + * + * @param reference + * @param binding + * @return + */ + private InterfaceContract getInterfaceContract(ComponentReference reference, Binding binding) { + InterfaceContract interfaceContract = reference.getInterfaceContract(); + ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding); + if (provider != null) { + InterfaceContract bindingContract = provider.getBindingInterfaceContract(); + if (bindingContract != null) { + interfaceContract = bindingContract; + } + } + return interfaceContract.makeUnidirectional(false); + } + + /** + * Remove the runtime wires for a reference binding + * @param reference + */ + private void removeReferenceWires(ComponentReference reference) { + if (!(reference instanceof RuntimeComponentReference)) { + return; + } + // [rfeng] Comment out the following statements to avoid the on-demand activation + // RuntimeComponentReference runtimeRef = (RuntimeComponentReference)reference; + // runtimeRef.getRuntimeWires().clear(); + } + + /** + * Get the effective interface contract for the service binding + * + * @param service + * @param binding + * @return + */ + + + /** + * Remove runtime wires for a service binding + * + * @param component + * @param service + */ + + + + + + + + + + /** + * @return the referenceHelper + */ + public CompositeContext getCompositeContext() { + return compositeContext; + } + + /** + * @return the domainComposite + */ + public Composite getDomainComposite() { + return domainComposite; + } + + /** + * @param domainComposite the domainComposite to set + */ + public void setDomainComposite(Composite domainComposite) { + this.domainComposite = domainComposite; + } + + public Component resolve(String componentURI) { + for (Composite composite : domainComposite.getIncludes()) { + Component component = resolve(composite, componentURI); + if (component != null) { + return component; + } + } + return null; + } + + public Component resolve(Composite composite, String componentURI) { + for (Component component : composite.getComponents()) { + String uri = component.getURI(); + if (uri.equals(componentURI)) { + return component; + } + if (componentURI.startsWith(uri)) { + Implementation implementation = component.getImplementation(); + if (!(implementation instanceof Composite)) { + return null; + } + return resolve((Composite)implementation, componentURI); + } + } + return null; + } + +} diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl2.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl2.java new file mode 100644 index 0000000000..a9150a8dc7 --- /dev/null +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl2.java @@ -0,0 +1,485 @@ +/* + * 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.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Contract; +import org.apache.tuscany.sca.assembly.Endpoint2; +import org.apache.tuscany.sca.assembly.EndpointReference2; +import org.apache.tuscany.sca.core.conversation.ConversationManager; +import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor; +import org.apache.tuscany.sca.core.invocation.RuntimeWireInvoker; +import org.apache.tuscany.sca.core.invocation.impl.InvocationChainImpl; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.InvocationChain; +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.provider.ImplementationProvider; +import org.apache.tuscany.sca.provider.PolicyProvider; +import org.apache.tuscany.sca.provider.PolicyProviderRRB; +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.EndpointReference; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; +import org.apache.tuscany.sca.runtime.RuntimeWire; +import org.apache.tuscany.sca.runtime.RuntimeWireProcessor; +import org.apache.tuscany.sca.work.WorkScheduler; +import org.oasisopen.sca.ServiceRuntimeException; + +/** + * @version $Rev$ $Date$ + */ +public class RuntimeWireImpl2 implements RuntimeWire { + private Boolean isReferenceWire = false; + private EndpointReference2 endpointReference; + private Endpoint2 endpoint; + + private transient RuntimeWireProcessor wireProcessor; + private transient InterfaceContractMapper interfaceContractMapper; + private transient WorkScheduler workScheduler; + private transient MessageFactory messageFactory; + private transient ConversationManager conversationManager; + private transient RuntimeWireInvoker invoker; + + // the following is a very simple cache that avoids re-cloning a wire + // when consecutive callbacks to the same endpoint are made + private EndpointReference lastCallback; + private RuntimeWire cachedWire; + private boolean wireReserved; + private RuntimeWireImpl2 clonedFrom; + + private List<InvocationChain> chains; + private InvocationChain bindingInvocationChain; + + /** + * @param source + * @param target + * @param interfaceContractMapper + * @param workScheduler + * @param wireProcessor + * @param messageFactory + * @param conversationManager + */ + public RuntimeWireImpl2(boolean isReferenceWire, + EndpointReference2 endpointReference, + Endpoint2 endpoint, + InterfaceContractMapper interfaceContractMapper, + WorkScheduler workScheduler, + RuntimeWireProcessor wireProcessor, + MessageFactory messageFactory, + ConversationManager conversationManager) { + super(); + this.isReferenceWire = isReferenceWire; + this.endpointReference = endpointReference; + this.endpoint = endpoint; + this.interfaceContractMapper = interfaceContractMapper; + this.workScheduler = workScheduler; + this.wireProcessor = wireProcessor; + this.messageFactory = messageFactory; + this.conversationManager = conversationManager; + this.invoker = new RuntimeWireInvoker(this.messageFactory, this.conversationManager, this); + } + + public synchronized List<InvocationChain> getInvocationChains() { + if (chains == null) { + initInvocationChains(); + } + return chains; + } + + public synchronized InvocationChain getBindingInvocationChain() { + if (bindingInvocationChain == null) { + bindingInvocationChain = new InvocationChainImpl(null, null, isReferenceWire); + if (isReferenceWire) { + initReferenceBindingInvocationChains(); + } else { + initServiceBindingInvocationChains(); + } + } + return bindingInvocationChain; + } + + public InvocationChain getInvocationChain(Operation operation) { + for (InvocationChain chain : getInvocationChains()) { + Operation op = null; + if (isReferenceWire) { + op = chain.getSourceOperation(); + } else { + op = chain.getTargetOperation(); + } + if (interfaceContractMapper.isCompatible(operation, op, op.getInterface().isRemotable())) { + return chain; + } + } + return null; + } + + public Object invoke(Message msg) throws InvocationTargetException { + return getBindingInvocationChain().getHeadInvoker().invoke(msg); + } + + public Object invoke(Operation operation, Object[] args) throws InvocationTargetException { + Message msg = messageFactory.createMessage(); + msg.setBody(args); + return invoker.invoke(operation, msg); + } + + public Object invoke(Operation operation, Message msg) throws InvocationTargetException { + return invoker.invoke(operation, msg); + } + + /** + * Initialize the invocation chains + */ + private void initInvocationChains() { + chains = new ArrayList<InvocationChain>(); + InterfaceContract sourceContract = endpointReference.getInterfaceContract(); + InterfaceContract targetContract = endpoint.getInterfaceContract(); + + if (isReferenceWire) { + // It's the reference wire + RuntimeComponentReference reference = (RuntimeComponentReference)endpointReference.getReference(); + Binding refBinding = endpointReference.getBinding(); + for (Operation operation : sourceContract.getInterface().getOperations()) { + Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation); + if (targetOperation == null) { + throw new ServiceRuntimeException("No matching operation for " + operation.getName() + + " is found in reference " + + endpointReference.getComponent().getURI() + + "#" + + reference.getName()); + } + InvocationChain chain = new InvocationChainImpl(operation, targetOperation, true); + if (operation.isNonBlocking()) { + addNonBlockingInterceptor(reference, refBinding, chain); + } + addReferenceBindingInterceptor(reference, refBinding, chain, operation); + chains.add(chain); + } + + } else { + // It's the service wire + RuntimeComponentService service = (RuntimeComponentService)endpoint.getService(); + RuntimeComponent serviceComponent = (RuntimeComponent)endpoint.getComponent(); + Binding serviceBinding = endpoint.getBinding(); + for (Operation operation : sourceContract.getInterface().getOperations()) { + Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation); + if (targetOperation == null) { + throw new ServiceRuntimeException("No matching operation for " + operation.getName() + + " is found in service " + + serviceComponent.getURI() + + "#" + + service.getName()); + } + InvocationChain chain = new InvocationChainImpl(operation, targetOperation, false); + if (operation.isNonBlocking()) { + addNonBlockingInterceptor(service, serviceBinding, chain); + } + addServiceBindingInterceptor(service, serviceBinding, chain, operation); + addImplementationInterceptor(serviceComponent, service, chain, targetOperation); + chains.add(chain); + } + + } + wireProcessor.process(this); + } + + private void initReferenceBindingInvocationChains() { + RuntimeComponentReference reference = (RuntimeComponentReference)endpointReference.getReference(); + Binding referenceBinding = endpointReference.getBinding(); + + // add the binding interceptors to the reference binding wire + ReferenceBindingProvider provider = reference.getBindingProvider(referenceBinding); + if ((provider != null) && + (provider instanceof ReferenceBindingProviderRRB)){ + ((ReferenceBindingProviderRRB)provider).configureBindingChain(this); + } + + // add the policy interceptors to the service binding wire + // find out which policies are active + List<PolicyProvider> pps = ((RuntimeComponentReference)reference).getPolicyProviders(referenceBinding); + if (pps != null) { + for (PolicyProvider p : pps) { + if (p instanceof PolicyProviderRRB) { + Interceptor interceptor = ((PolicyProviderRRB)p).createBindingInterceptor(); + if (interceptor != null) { + bindingInvocationChain.addInterceptor(p.getPhase(), interceptor); + } + } + } + } + } + + private void initServiceBindingInvocationChains() { + RuntimeComponentService service = (RuntimeComponentService)endpoint.getService(); + Binding serviceBinding = endpoint.getBinding(); + + // add the binding interceptors to the service binding wire + ServiceBindingProvider provider = service.getBindingProvider(serviceBinding); + if ((provider != null) && + (provider instanceof ServiceBindingProviderRRB)){ + ((ServiceBindingProviderRRB)provider).configureBindingChain(this); + } + + // add the policy interceptors to the service binding wire + List<PolicyProvider> pps = ((RuntimeComponentService)service).getPolicyProviders(serviceBinding); + if (pps != null) { + for (PolicyProvider p : pps) { + if (p instanceof PolicyProviderRRB) { + Interceptor interceptor = ((PolicyProviderRRB)p).createBindingInterceptor(); + if (interceptor != null) { + bindingInvocationChain.addInterceptor(p.getPhase(), interceptor); + } + } + } + } + + + // TODO - add something on the end of the wire to invoke the + // invocation chain. Need to split out the runtime + // wire invoker into conversation, callback interceptors etc + bindingInvocationChain.addInvoker(invoker); + + } + + // TODO - remove. Just here during development + static EndpointReference epr; + + public EndpointReference getSource() { + // TODO - convert this into method that returns EndpointReference2 + epr = new EndpointReferenceImpl((RuntimeComponent)endpointReference.getComponent(), + endpointReference.getReference(), + endpointReference.getBinding(), + endpointReference.getInterfaceContract()); + + // TODO - somtimes used to reset the interface contract so we + // copy it back in in the rebuild method below + return epr; + } + + + + public EndpointReference getTarget() { + // TODO - convert this into method that return Endpoint2 + + EndpointReference epr = new EndpointReferenceImpl((RuntimeComponent)endpoint.getComponent(), + endpoint.getService(), + endpoint.getBinding(), + endpoint.getInterfaceContract()); + return epr; + } + + public void setTarget(EndpointReference target) { + // TODO - can we use the idea of setTarget to rebuild the wire? + + } + + public void rebuild() { + // TODO - can we use the idea of setTarget to rebuild the wire? + // used at the moment by binding.sca when it resets the + // source interface contract for local wires + this.chains = null; + + // TODO - cheating here as I fixed the RuntimeComponentService code + // to call this when it resets the interface contract + endpointReference.setInterfaceContract(epr.getInterfaceContract()); + } + + /** + * Add the interceptor for a reference binding + * + * @param reference + * @param binding + * @param chain + * @param operation + */ + private void addReferenceBindingInterceptor(ComponentReference reference, + Binding binding, + InvocationChain chain, + Operation operation) { + ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding); + if (provider != null) { + Invoker invoker = provider.createInvoker(operation); + if (invoker != null) { + chain.addInvoker(invoker); + } + } + List<PolicyProvider> pps = ((RuntimeComponentReference)reference).getPolicyProviders(binding); + if (pps != null) { + for (PolicyProvider p : pps) { + Interceptor interceptor = p.createInterceptor(operation); + if (interceptor != null) { + chain.addInterceptor(p.getPhase(), p.createInterceptor(operation)); + } + } + } + } + + /** + * Add the interceptor for a binding + * + * @param reference + * @param binding + * @param chain + * @param operation + */ + private void addServiceBindingInterceptor(ComponentService service, + Binding binding, + InvocationChain chain, + Operation operation) { + List<PolicyProvider> pps = ((RuntimeComponentService)service).getPolicyProviders(binding); + if (pps != null) { + for (PolicyProvider p : pps) { + Interceptor interceptor = p.createInterceptor(operation); + if (interceptor != null) { + chain.addInterceptor(p.getPhase(), p.createInterceptor(operation)); + } + } + } + } + + /** + * Add a non-blocking interceptor if the reference binding needs it + * + * @param reference + * @param binding + * @param chain + */ + private void addNonBlockingInterceptor(ComponentReference reference, Binding binding, InvocationChain chain) { + ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding); + if (provider != null) { + boolean supportsOneWayInvocation = provider.supportsOneWayInvocation(); + if (!supportsOneWayInvocation) { + chain.addInterceptor(Phase.REFERENCE, new NonBlockingInterceptor(workScheduler)); + } + } + } + + /** + * Add a non-blocking interceptor if the service binding needs it + * + * @param service + * @param binding + * @param chain + */ + private void addNonBlockingInterceptor(ComponentService service, Binding binding, InvocationChain chain) { + ServiceBindingProvider provider = ((RuntimeComponentService)service).getBindingProvider(binding); + if (provider != null) { + if (!provider.supportsOneWayInvocation()) { + chain.addInterceptor(Phase.SERVICE, new NonBlockingInterceptor(workScheduler)); + } + } + } + + /** + * Add the interceptor for a component implementation + * + * @param component + * @param service + * @param chain + * @param operation + */ + private void addImplementationInterceptor(Component component, + ComponentService service, + InvocationChain chain, + Operation operation) { + ImplementationProvider provider = ((RuntimeComponent)component).getImplementationProvider(); + if (provider != null) { + Invoker invoker = null; + invoker = provider.createInvoker((RuntimeComponentService)service, operation); + chain.addInvoker(invoker); + } + List<PolicyProvider> pps = ((RuntimeComponent)component).getPolicyProviders(); + if (pps != null) { + for (PolicyProvider p : pps) { + Interceptor interceptor = p.createInterceptor(operation); + if (interceptor != null) { + chain.addInterceptor(p.getPhase(), p.createInterceptor(operation)); + } + } + } + } + + /** + * @see java.lang.Object#clone() + */ + @Override + public Object clone() throws CloneNotSupportedException { + RuntimeWireImpl2 copy = (RuntimeWireImpl2)super.clone(); + copy.endpointReference = (EndpointReference2)endpointReference.clone(); + copy.endpoint = (Endpoint2)endpoint.clone(); + copy.invoker = new RuntimeWireInvoker(copy.messageFactory, copy.conversationManager, copy); + copy.cachedWire = null; // TUSCANY-2630 + return copy; + } + + /** + * @return the conversationManager + */ + public ConversationManager getConversationManager() { + return conversationManager; + } + + public synchronized RuntimeWire lookupCache(EndpointReference callback) { + if (lastCallback != null && callback.getURI().equals(lastCallback.getURI()) && !wireReserved) { + wireReserved = true; + return cachedWire; + } else { + return null; + } + } + + public synchronized void addToCache(EndpointReference callback, RuntimeWire clonedWire) { + ((RuntimeWireImpl2)clonedWire).setClonedFrom(this); + lastCallback = callback; + cachedWire = clonedWire; + wireReserved = true; + } + + public synchronized void releaseClonedWire(RuntimeWire wire) { + if (cachedWire == wire) { + wireReserved = false; + } + } + + public synchronized void releaseWire() { + clonedFrom.releaseClonedWire(this); + } + + private void setClonedFrom(RuntimeWireImpl2 wire) { + clonedFrom = wire; + } +} |