You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by sl...@apache.org on 2010/01/10 15:04:25 UTC

svn commit: r897639 [2/2] - in /tuscany/sca-java-2.x/trunk/modules: assembly/src/main/java/org/apache/tuscany/sca/assembly/ assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/ builder/ builder/META-INF/ builder/src/main/java/org/apache/tuscany...

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=897639&r1=897638&r2=897639&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 Sun Jan 10 14:04:24 2010
@@ -22,15 +22,10 @@
 import java.util.List;
 
 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.Endpoint;
 import org.apache.tuscany.sca.assembly.EndpointReference;
 import org.apache.tuscany.sca.assembly.Multiplicity;
-import org.apache.tuscany.sca.assembly.SCABinding;
-import org.apache.tuscany.sca.assembly.builder.Messages;
 import org.apache.tuscany.sca.core.ExtensionPointRegistry;
 import org.apache.tuscany.sca.core.FactoryExtensionPoint;
 import org.apache.tuscany.sca.core.UtilityExtensionPoint;
@@ -46,8 +41,8 @@
  * 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 so that the mechanism for reference/service matching 
- * can be replaced independently
+ * This is a separate from the builders so that the mechanism for reference/service matching 
+ * can be used at runtime as well as build time and can also be replaced independently
  *
  * @version $Rev$ $Date$
  */
@@ -72,19 +67,48 @@
     }
     
     /**
-     * Match a reference with a service endpoint
+     * Bind a single endpoint reference at build time. Here we only expect the
+     * registry to have a record of local endpoints
+     *
+     * @param endpointRegistry
+     * @param endpointReference
+     */
+    public boolean bindBuildTime(EndpointRegistry endpointRegistry, 
+                                 EndpointReference endpointReference) {
+       return bind(endpointRegistry, endpointReference, false);
+    }
+    
+    /**
+     * Bind a single endpoint reference at build time. Here we expect the
+     * registry to be populated with endpoints from across the domain
+     *
+     * @param endpointRegistry
+     * @param endpointReference
+     */
+    public boolean bindRunTime(EndpointRegistry endpointRegistry,
+                               EndpointReference endpointReference) {
+        return bind(endpointRegistry, endpointReference, true);
+    }
+    
+    /**
+     * Bind a reference to a service endpoint
      * 
-     * Taking a look a consolidating the match logic that used to be in the
-     * EndpointReferenceBuilder with the match logic that is in the bind() 
-     * method below
+     * @param endpointRegistry
+     * @param endpointReference
+     * @param runtime set true if called from the runtime 
      */
-    public boolean match(EndpointRegistry endpointRegistry,  
-                         EndpointReference endpointReference){
+    public boolean bind(EndpointRegistry endpointRegistry,  
+                         EndpointReference endpointReference,
+                         boolean runtime){
         
         Problem problem = null;
-        
-        if (endpointReference.getStatus() == EndpointReference.AUTOWIRE_PLACEHOLDER){
+             
+        // This logic does post build autowire matching but isn't actually used at the moment
+        // as problems with dependencies mean we still do this during build
+        if (endpointReference.getStatus() == EndpointReference.AUTOWIRE_PLACEHOLDER){ 
+           
             // do autowire matching
+            // will only be called at build time at the moment
             Multiplicity multiplicity = endpointReference.getReference().getMultiplicity();
             for (Endpoint endpoint : endpointRegistry.getEndpoints()){
 //              if (endpoint is in the same composite as endpoint reference){
@@ -122,12 +146,12 @@
                                 // won't happen as clone is supported
                             }
                             
-                            autowireEndpointRefrence.setTargetEndpoint(autowireEndpoint);
+                            autowireEndpointRefrence.setTargetEndpoint(endpoint);
+                            autowireEndpointRefrence.setBinding(endpoint.getBinding());
                             autowireEndpointRefrence.setStatus(EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED);
                             endpointReference.getReference().getEndpointReferences().add(autowireEndpointRefrence);  
                         }
                     }
-                    
 //              }
             }
             
@@ -135,11 +159,14 @@
                 if (endpointReference.getReference().getEndpointReferences().size() == 1) {
                     Monitor.error(monitor,
                                   this,
-                                  Messages.ASSEMBLY_VALIDATION,
+                                  "endpoint-validation-messages",
                                   "NoComponentReferenceTarget",
                                   endpointReference.getReference().getName());
                 }
             }
+            
+            setSingleAutoWireTarget(endpointReference.getReference());
+            
         } else if ( endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED||
                     endpointReference.getStatus() == EndpointReference.RESOLVED_BINDING ) {
             // The endpoint reference is already resolved to either
@@ -153,12 +180,47 @@
                 problem = selectCallbackEndpoint(endpointReference,
                                                  endpointReference.getReference().getCallbackService().getEndpoints());
             } 
-        } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_NOT_FOUND ||
+        } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_READY_FOR_MATCHING ){
+            // The endpoint reference is already resolved to either
+            // a service endpoint but no binding was specified in the 
+            // target URL and/or the policies have yet to be matched.
+            // TODO - is this really required now
+            
+            problem = selectForwardEndpoint(endpointReference,
+                                            endpointReference.getTargetEndpoint().getService().getEndpoints());
+
+            if (problem == null && hasCallback(endpointReference)){
+                problem = selectCallbackEndpoint(endpointReference,
+                                                 endpointReference.getReference().getCallbackService().getEndpoints());
+            }             
+        } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_IN_BINDING_URI ||
+                   endpointReference.getStatus() == EndpointReference.WIRED_TARGET_NOT_FOUND ||
                    endpointReference.getStatus() == EndpointReference.NOT_CONFIGURED){
             // The reference is not yet matched to a service
-
+          
             // find the service in the endpoint registry
             List<Endpoint> endpoints = endpointRegistry.findEndpoint(endpointReference);
+            
+            if ((endpoints.size() == 0) && 
+                (runtime == true)     ) {
+                
+                // tweak to test if this could be a resolve binding. If the uri 
+                // has come from the binding (as opposed to a reference target) 
+                // the assume that it is. 
+                String bindingURI = endpointReference.getBinding().getURI();
+                if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_IN_BINDING_URI){
+                    endpointReference.getTargetEndpoint().setBinding(endpointReference.getBinding());
+                    endpointReference.setRemote(true);
+                    endpointReference.setStatus(EndpointReference.RESOLVED_BINDING);
+                } else {
+                    problem = monitor.createProblem(this.getClass().getName(), 
+                                                    "endpoint-validation-messages", 
+                                                    Problem.Severity.ERROR, 
+                                                    this, 
+                                                    "NoEndpointsFound", 
+                                                    endpointReference.toString());
+                }
+            }            
 
             problem = selectForwardEndpoint(endpointReference,
                                             endpoints);
@@ -177,9 +239,6 @@
         if (endpointReference.getStatus() != EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED &&
             endpointReference.getStatus() != EndpointReference.RESOLVED_BINDING){
             
-            // how to tell between runtime and build time
-            boolean runtime = false;
-            
             if (runtime){
                 problem = monitor.createProblem(this.getClass().getName(), 
                                                 "endpoint-validation-messages", 
@@ -189,7 +248,7 @@
                                                 endpointReference.toString());
             } else {
                 problem = monitor.createProblem(this.getClass().getName(), 
-                                                Messages.ASSEMBLY_VALIDATION, 
+                                                "endpoint-validation-messages", 
                                                 Problem.Severity.WARNING, 
                                                 this, 
                                                 "ComponentReferenceTargetNotFound",
@@ -202,89 +261,27 @@
         }
        
         return true;
-    }
-
+    }    
+   
     /**
-     * Build a single endpoint reference
-     *
-     * @param invocable
-     * @param monitor
+     * Returns true if the reference has a callback
      */
-    public boolean bind(EndpointRegistry endpointRegistry, 
-                        EndpointReference endpointReference) {
-        Problem problem = null;
-        if ( endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED ||
-             endpointReference.getStatus() == EndpointReference.RESOLVED_BINDING ) {
-            // The endpoint reference is already resolved to either
-            // a service endpoint local to this composite or it has
-            // a remote binding
-            
-            // still need to check that the callback endpoint is set correctly
-            if (hasCallback(endpointReference) &&
-                endpointReference.getCallbackEndpoint() != null &&
-                endpointReference.getCallbackEndpoint().isUnresolved() == true ){
-                problem = selectCallbackEndpoint(endpointReference,
-                                                 endpointReference.getReference().getCallbackService().getEndpoints());
-            } 
-        } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_READY_FOR_MATCHING ){
-            // The endpoint reference is already resolved to either
-            // a service endpoint but no binding was specified in the 
-            // target URL and/or the policies have yet to be matched.         
-            
-            problem = selectForwardEndpoint(endpointReference,
-                                            endpointReference.getTargetEndpoint().getService().getEndpoints());
-
-            if (problem == null && hasCallback(endpointReference)){
-                problem = selectCallbackEndpoint(endpointReference,
-                                                 endpointReference.getReference().getCallbackService().getEndpoints());
-            } 
-            
-        } else if (endpointReference.getStatus() == EndpointReference.WIRED_TARGET_NOT_FOUND ||
-                   endpointReference.getStatus() == EndpointReference.NOT_CONFIGURED){
-            // The service is in a remote composite somewhere else in the domain
-
-            // find the service in the endpoint registry
-            List<Endpoint> endpoints = endpointRegistry.findEndpoint(endpointReference);
-
-            if (endpoints.size() == 0) {
-                problem = monitor.createProblem(this.getClass().getName(), 
-                                                "endpoint-validation-messages", 
-                                                Problem.Severity.ERROR, 
-                                                this, 
-                                                "NoEndpointsFound", 
-                                                endpointReference.toString());
-            }
-
-            problem = selectForwardEndpoint(endpointReference,
-                                            endpoints);
-
-            if (problem == null && hasCallback(endpointReference)){
-                problem = selectCallbackEndpoint(endpointReference,
-                                                 endpointReference.getReference().getCallbackService().getEndpoints());
-            }             
-        } 
-        
-        if (problem != null){
-            monitor.problem(problem);
-            return false;
-        }
-
-        if (endpointReference.getStatus() != EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED &&
-            endpointReference.getStatus() != EndpointReference.RESOLVED_BINDING){
-            problem = monitor.createProblem(this.getClass().getName(), 
-                                            "endpoint-validation-messages", 
-                                            Problem.Severity.ERROR, 
-                                            this, 
-                                            "EndpointReferenceCantBeMatched", 
-                                            endpointReference.toString());
-            monitor.problem(problem);
+    private boolean hasCallback(EndpointReference endpointReference){
+        if (endpointReference.getReference().getInterfaceContract() == null ||
+            endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null ||
+            endpointReference.getReference().getName().startsWith("$self$.")){
             return false;
+        } else {
+            return true;
         }
-        
-        return true;
-        
     }
 
+    /**
+     * Selects a forward endpoint from a list of possible candidates
+     * 
+     * @param endpointReference
+     * @param endpoints
+     */
     private Problem selectForwardEndpoint(EndpointReference endpointReference, List<Endpoint> endpoints) {    
              
         Endpoint matchedEndpoint = null;
@@ -314,17 +311,13 @@
         
         return null;
     }
-    
-    private boolean hasCallback(EndpointReference endpointReference){
-        if (endpointReference.getReference().getInterfaceContract() == null ||
-            endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null ||
-            endpointReference.getReference().getName().startsWith("$self$.")){
-            return false;
-        } else {
-            return true;
-        }
-    }
 
+    /**
+     * Selects a callback endpoint from a list of possible candidates
+     * 
+     * @param endpointReference
+     * @param endpoints
+     */
     private Problem selectCallbackEndpoint(EndpointReference endpointReference, List<Endpoint> endpoints) {
 
         Problem problem = null;
@@ -336,7 +329,7 @@
         for ( EndpointReference callbackEndpointReference : endpointReference.getTargetEndpoint().getCallbackEndpointReferences()){
             for (Endpoint endpoint : endpoints){
                 if (haveMatchingPolicy(callbackEndpointReference, endpoint) &&
-                    haveMatchingInterfaceContracts(endpointReference, endpoint)){
+                    haveMatchingInterfaceContracts(callbackEndpointReference, endpoint)){
                     matchedEndpoint = endpoint;
                     break match;
                 }
@@ -353,7 +346,7 @@
     }
 
     /**
-     * Determine in endpoint reference and endpoint policies match 
+     * Determine if endpoint reference and endpoint policies match 
      */
     private boolean haveMatchingPolicy(EndpointReference endpointReference, Endpoint endpoint){
         
@@ -425,31 +418,101 @@
         */
         
         return true;
+        
+        /* 
+        Some new psuedo code based on the spec
+        // if we have intents without policy sets we need to match those at the intent level 
+        // before doing policy set matching
+
+        If policy set QNames from epr and er match exactly
+           return true
+
+        if policy set languages at ep are not all the same 
+           raise error (probably would have done this earlier)
+           should go in policy processor
+           how to tell which language is expected by a binding
+
+        if policy set languages at epr are not all the same
+           raise error (probably would have done this earlier)
+           should go in policy processor
+           how to tell which language is expected by a binding
+
+         if policy set language at ep and epr are not the same
+           raise error 
+           should be the same binding at both ends so should have same
+           languages
+
+         find the language specific policy matcher
+
+         return languageSpecificMatcher.match(policy sets from epr, policy sets from ep)
+         // not sure how a matcher aggregates multiple policy sets to find the intersection. 
+         // expect that is language specific 
+         */
     }
     
     /**
-     * Determine in endpoint reference and endpoint interface contracts match 
+     * Determine if endpoint reference and endpoint interface contracts match 
      */
     private boolean haveMatchingInterfaceContracts(EndpointReference endpointReference, Endpoint endpoint){
-        return true;
-/* this breaks the existing matching code
         if (endpointReference.getReference().getInterfaceContract() == null){
             return true;
         }
+        
+        // TODO - is there a better test for this. Would have to cast to the
+        //        correct iface type to get to the resolved flag
+        if (endpoint.getComponentServiceInterfaceContract().getInterface().getOperations().size() == 0){
+            // the interface contract is likely remote but unresolved
+            // we discussed this on the ML and decided that we could
+            // live with this for the case where there is no central matching of references
+            // to services. Any errors will be detected when the message flows. 
+            return true;
+        }
              
         return interfaceContractMapper.isCompatible(endpointReference.getReference().getInterfaceContract(), 
                                                     endpoint.getComponentServiceInterfaceContract());
-*/
     }
     
-
+    /**
+     * Checks to see if the registry has been updated since the reference was last matched
+     * 
+     * @return true is the registry has changed
+     */
     public boolean isOutOfDate(EndpointRegistry endpointRegistry, EndpointReference endpointReference) {
         Endpoint te = endpointReference.getTargetEndpoint();
-        if (!te.isUnresolved() && te.getURI()!= null) {
+        if (te!= null && !te.isUnresolved() && te.getURI()!= null) {
             List<Endpoint> endpoints = endpointRegistry.findEndpoint(endpointReference);
             return ! endpoints.contains(endpointReference.getTargetEndpoint());
         }
         return false;
     }
 
+    /**
+     * ASM_5021: where a <reference/> of a <component/> has @autowire=true 
+     * and where the <reference/> has a <binding/> child element which 
+     * declares a single target service,  the reference is wired only to 
+     * the single service identified by the <wire/> element
+     */    
+    private void setSingleAutoWireTarget(ComponentReference reference) {
+        if (reference.getEndpointReferences().size() > 1 && reference.getBindings() != null
+            && reference.getBindings().size() == 1) {
+            String uri = reference.getBindings().get(0).getURI();
+            if (uri != null) {
+                if (uri.indexOf('/') > -1) {
+                    // TODO: must be a way to avoid this fiddling
+                    int i = uri.indexOf('/');
+                    String c = uri.substring(0, i);
+                    String s = uri.substring(i + 1);
+                    uri = c + "#service(" + s + ")";
+                }
+                for (EndpointReference er : reference.getEndpointReferences()) {
+                    if (er.getTargetEndpoint() != null && uri.equals(er.getTargetEndpoint().getURI())) {
+                        reference.getEndpointReferences().clear();
+                        reference.getEndpointReferences().add(er);
+                        return;
+                    }
+                }
+            }
+        }
+    }
+  
 }