Author: slaws
Date: Thu Aug 25 11:59:58 2011
New Revision: 1161527

URL: http://svn.apache.org/viewvc?rev=1161527&view=rev
Log:
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. 

Modified:
    
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java
    
tuscany/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java
    
tuscany/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java
    
tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java

Modified: 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java?rev=1161527&r1=1161526&r2=1161527&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java
 Thu Aug 25 11:59:58 2011
@@ -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 B
                     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;

Modified: 
tuscany/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java?rev=1161527&r1=1161526&r2=1161527&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WebServiceBindingBuilder.java
 Thu Aug 25 11:59:58 2011
@@ -45,9 +45,11 @@ public class WebServiceBindingBuilder im
      * 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());

Modified: 
tuscany/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java?rev=1161527&r1=1161526&r2=1161527&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java
 Thu Aug 25 11:59:58 2011
@@ -771,7 +771,7 @@ public class EndpointReferenceBuilderImp
      * 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 EndpointReferenceBuilderImp
      *        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 EndpointReferenceBuilderImp
             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;
                 } 
             } 
         } 

Modified: 
tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java?rev=1161527&r1=1161526&r2=1161527&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java
 Thu Aug 25 11:59:58 2011
@@ -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
     }
 
     /**
-     * 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
             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
             }
         } 
         
-        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
             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);
         }        


Reply via email to