diff options
author | slaws <slaws@13f79535-47bb-0310-9956-ffa450edef68> | 2011-08-25 11:59:58 +0000 |
---|---|---|
committer | slaws <slaws@13f79535-47bb-0310-9956-ffa450edef68> | 2011-08-25 11:59:58 +0000 |
commit | ce82a7f210ae1567db740532e451a9ec28f176b9 (patch) | |
tree | 7b28a1ef814cadd26213b3fe9ee7197e6c4c765c /sca-java-2.x | |
parent | f35d48772e6d3bf5c4a2006cf23bf4731e420b1b (diff) |
TUSCANY-3932 - Rework the callack wire calculation to be based on non-runtime configurations. I've modified the Endpoint writing algorithm to write out automatically calculated callback bindings as well as callback bindings specified explicitly by the user.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1161527 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x')
4 files changed, 140 insertions, 50 deletions
diff --git a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java index d128897df0..9f323a5507 100644 --- a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java +++ b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java @@ -26,10 +26,12 @@ import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Callback; import org.apache.tuscany.sca.assembly.Component; import org.apache.tuscany.sca.assembly.ComponentService; 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.contribution.processor.ContributionReadException; import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; import org.apache.tuscany.sca.contribution.processor.ContributionWriteException; @@ -114,7 +116,20 @@ public class EndpointProcessor extends BaseAssemblyProcessor implements StAXArti if (endpoint.getBinding() != null) { Binding binding = (Binding)endpoint.getBinding().clone(); service.getBindings().add(binding); - } + } + // put both manually configured AND automatically generated callback bindings + // into the wrapping model so that we can pass callback configuarion via + // the registry + if (service.getCallbackReference() != null) { + Callback callback = service.getCallback(); + if(callback == null){ + callback = assemblyFactory.createCallback(); + } + for (EndpointReference epr : service.getCallbackReference().getEndpointReferences()){ + callback.getBindings().add(epr.getBinding()); + } + service.setCallback(callback); + } } } return composite; diff --git a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java index 0117ee5d79..2b24df92d2 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java +++ b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java @@ -45,9 +45,11 @@ public class WebServiceBindingBuilder implements BindingBuilder<WebServiceBindin * Create a calculated WSDL document and save it in the Web Service binding. */ public void build(Component component, Contract contract, WebServiceBinding binding, BuilderContext context, boolean rebuild) { - // in some cases (callback service endpoint processing) we need to re-generate the - // WSDL doc from a ws binding that already has one. + // in some cases (callback service endpoint processing) we need to re-set the binding interface contract + // and re-generate the WSDL doc from it. This is because the callback binding may be cloned from the + // forward binding if (rebuild == true){ + binding.setBindingInterfaceContract(null); binding.setGeneratedWSDLDocument(null); } BindingWSDLGenerator.generateWSDL(component, contract, binding, extensionPoints, context.getMonitor()); diff --git a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java index ada790163f..54a5e826b6 100644 --- a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java +++ b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java @@ -771,7 +771,7 @@ public class EndpointReferenceBuilderImpl { * to present the callback services and references. These are identifiable as their names * will match the name of the forward reference or service to which they relate. In the general * endpoint reference and endpoint processing we will have created endpoints and endpoint references - * for these callback services and references. We now need to related forward endpoint references with + * for these callback services and references. We now need to relate forward endpoint references with * callback endpoints and forward endpoints with callback endpoint references. Here's the model... * * Client Component Target Component @@ -782,8 +782,11 @@ public class EndpointReferenceBuilderImpl { * Service \/ (for the callback) Reference \/ (for the callback) * Endpoint <--------------------------------------------EndpointReference * - * TODO - there are issues here with callback binding multiplicities and which callback - * endpoint is associated with which endpointreference + * TODO - there are issues here with callback binding multiplicities that the OASIS spec + * is not very clear on. We need to decide which callback endpoint is associated with + * which endpointreference. For the time being we select the first one that matches the + * forward binding type as we assume that the user is simply using the callback binding + * configuration to further configure the type of binding they used for the forward call. * * @param reference * @param component @@ -796,22 +799,33 @@ public class EndpointReferenceBuilderImpl { List<Endpoint> callbackEndpoints = reference.getCallbackService().getEndpoints(); if (!callbackEndpoints.isEmpty()) { for (EndpointReference endpointReference : reference.getEndpointReferences()){ - // [rfeng] FIXME: how to select the callback endpoints? - endpointReference.setCallbackEndpoint(callbackEndpoints.get(0)); + for(Endpoint callbackEndpoint : callbackEndpoints){ + if((endpointReference.getBinding() != null) && + (callbackEndpoint.getBinding() != null) && + (callbackEndpoint.getBinding().getType().equals(endpointReference.getBinding().getType()))){ + endpointReference.setCallbackEndpoint(callbackEndpoint); + break; + } + } } } } // fix up links between endpoints and endpoint references that represent callbacks for (ComponentService service : component.getServices()) { - if ((service.getInterfaceContract() != null) && (service.getInterfaceContract() - .getCallbackInterface() != null)) { + if ((service.getInterfaceContract() != null) && + (service.getInterfaceContract().getCallbackInterface() != null)) { if (reference.getName().equals(service.getName())) { for (Endpoint endpoint : service.getEndpoints()) { - endpoint.getCallbackEndpointReferences().addAll(reference - .getEndpointReferences()); + for ( EndpointReference callbackEndpointReference : reference.getEndpointReferences()){ + if((endpoint.getBinding() == null) && + (callbackEndpointReference.getBinding() == null) && + (callbackEndpointReference.getBinding().getType().equals(endpoint.getBinding().getType()))){ + endpoint.getCallbackEndpointReferences().add(callbackEndpointReference); + break; + } + } } - break; } } } diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java index 6b87b55afc..a61b549489 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java @@ -29,6 +29,7 @@ import javax.xml.namespace.QName; import org.apache.tuscany.sca.assembly.AssemblyFactory; import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Callback; import org.apache.tuscany.sca.assembly.ComponentReference; import org.apache.tuscany.sca.assembly.ComponentService; import org.apache.tuscany.sca.assembly.Endpoint; @@ -463,54 +464,106 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { } /** - * Selects a callback endpoint from a list of possible candidates + * This code is very similar to the code in EnpointReferenceBuilder.fixUpCallbackLinks() + * but here we are selecting endpoint/endpoint references at runtime. + * + * To recap the general model is as follows: + * + * Forward EPR -----------> Forward EP (target EP) + * | | + * \/ \/ + * Callback EP <------------ Callback EPR + * + * The question then becomes how to construct this model given that + * target resolution can happen at runtime and EPR and EP can be + * distributed across the domain. + * + * The forward link is resolved by searching in the registry for an EP + * that matches the EPR. + * + * At build time we've made the assumption that, if the user configures + * a callback binding at all, they will choose the same binding as the + * forward call (TODO - this may be a bold assumption). So here we just + * assume that the callback endpoint that is set on the reference + * at build time matches. This may not be true if the callback bindings + * are configured differently on the reference and service. * * @param endpointReference * @param endpoints */ private void selectCallbackEndpoint(EndpointReference endpointReference, ComponentService callbackService, Audit matchAudit, BuilderContext builderContext, boolean runtime) { - - // find the first callback endpoint that matches a callback endpoint reference - // at the service + + // A simplifying assumption here is that the user will only specify a callback binding + // of the same type as the forward binding in order to specify further configuration + // We can then assume that if there is no callback endpoint that matches already then we have + // picked up binding config from the service and we can create a callback endpoint to match + + // So having said this we look in three places for the callback binding. + // 1/ in callback endpoints at the reference + // - will find it here if the user has manually configured a callback binding at the reference + // 2/ in the service callback structure + // - will find it here if the user has manually configured a callback binding at the service + // 3/ in the service callback reference structure + // - will find it here if the system has constructed the callback binding based on the forward binding + // + // 2 and 3 are conflated in the distributed case as be write any derived callback bindings out into the + // callback structure as the endpoint is serialized across the domain + RuntimeEndpoint callbackEndpoint = null; - match: - for ( EndpointReference callbackEndpointReference : endpointReference.getTargetEndpoint().getCallbackEndpointReferences()){ - for (Endpoint endpoint : callbackService.getEndpoints()){ - if (haveMatchingPolicy(callbackEndpointReference, endpoint, matchAudit, builderContext) && - haveMatchingInterfaceContracts(callbackEndpointReference, endpoint, matchAudit)){ - callbackEndpoint = (RuntimeEndpoint)endpoint; - break match; - } + + // 1/ look in callback endpoints at the reference + // - exploiting the assumption that the user will specific callback bindings of + // the same type as the forward binding + match1: + for(Endpoint loopCallbackEndpoint : callbackService.getEndpoints()){ + if(loopCallbackEndpoint.getBinding().getType().equals(endpointReference.getBinding().getType())){ + callbackEndpoint = (RuntimeEndpoint)loopCallbackEndpoint; + break match1; } - } + } - // if no callback endpoint was found or if the binding is the SCA binding and it doesn't match - // the forward binding then create a new callback endpoint - // TODO - there is a hole here in that the user may explicitly specify an SCA binding for the - // callback that is different from the forward binding. Waiting for feedback form OASIS - // before doing more drastic surgery to fix this corner case as there are other things - // wrong with the default case, such as what to do about policy - if (callbackEndpoint == null || - (callbackEndpoint.getBinding().getType().equals(SCABinding.TYPE) && - !endpointReference.getBinding().getType().equals(SCABinding.TYPE))){ - // no endpoint in place so we need to create one + // if no callback endpoint was found then create a new callback endpoint + if (callbackEndpoint == null ){ callbackEndpoint = (RuntimeEndpoint)assemblyFactory.createEndpoint(); callbackEndpoint.setComponent(endpointReference.getComponent()); callbackEndpoint.setService(callbackService); Binding forwardBinding = endpointReference.getBinding(); Binding callbackBinding = null; - for (EndpointReference callbackEPR : endpointReference.getTargetEndpoint().getCallbackEndpointReferences()){ - if (callbackEPR.getBinding().getType().equals(forwardBinding.getType())){ - try { - callbackBinding = (Binding)callbackEPR.getBinding().clone(); - } catch (CloneNotSupportedException ex){ - - } - break; + + // 2/ look in the service callback structure + Callback serviceCallback = endpointReference.getTargetEndpoint().getService().getCallback(); + + if (serviceCallback != null){ + for(Binding loopCallbackBinding : serviceCallback.getBindings()){ + if(loopCallbackBinding.getType().equals(endpointReference.getBinding().getType())){ + callbackBinding = loopCallbackBinding; + break; + } + } + } + + // 3/ look in the service endpoint callback reference structure + ComponentReference callbackReference = endpointReference.getTargetEndpoint().getService().getCallbackReference(); + + if (callbackReference != null){ + for (EndpointReference loopEndpointReference : callbackReference.getEndpointReferences()){ + if (loopEndpointReference.getBinding().getType().equals(endpointReference.getBinding().getType())){ + callbackBinding = loopEndpointReference.getBinding(); + break; + } } } + // if all else fails clone the forward binding + // TODO - do we ever get here? + if (callbackBinding == null){ + try { + callbackBinding = (Binding)forwardBinding.clone(); + } catch (CloneNotSupportedException ex){ + } + } + // get the callback binding URI by looking at the SCA binding // that will have been added at build time callbackBinding.setURI(null); @@ -530,7 +583,7 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { build(callbackEndpoint); // Only activate the callback endpoint if the bind is being done at runtime - // and hence everything else is running. If we don't activate here then the + // and hence everything else is running. If it's build time then the // endpoint will be activated at the same time as all the other endpoints if (runtime) { // activate it @@ -543,7 +596,8 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { } } - endpointReference.setCallbackEndpoint(callbackEndpoint); + // finally set the callback endpoint into the forward reference + endpointReference.setCallbackEndpoint(callbackEndpoint); } private void build(Endpoint endpoint) { @@ -913,13 +967,18 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { matchAudit.append("Match because there is no interface contract on the reference "); matchAudit.appendSeperator(); return true; - } + } + + if (endpoint.isRemote()){ + matchAudit.append("Match because endpoint is remote"); + matchAudit.appendSeperator(); + return true; + } - // If the contracts are not of the same type or normalized interfaces are available - // use them + // If the contracts are not of the same type use normailized interfaces if (endpointReferenceContract.getClass() != endpointContract.getClass() || endpointReferenceContract.getNormalizedWSDLContract() != null || - endpointContract.getNormalizedWSDLContract() != null) { + endpointContract.getNormalizedWSDLContract() != null) { endpointReferenceContract = ((RuntimeEndpointReference)endpointReference).getGeneratedWSDLContract(endpointReferenceContract); endpointContract = ((RuntimeEndpoint)endpoint).getGeneratedWSDLContract(endpointContract); } |