From 8595fcf695df2c851d792c67545f56548f791547 Mon Sep 17 00:00:00 2001 From: slaws Date: Sun, 10 Jan 2010 14:04:24 +0000 Subject: TUSCANY-3417 TUSCANY-3417 consolidate enpointreference/endpoint matching code into the binding. There is currently a bit, related to autowiring, still left on the builders awaiting some dependency juggling git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@897639 13f79535-47bb-0310-9956-ffa450edef68 --- .../impl/RuntimeEndpointReferenceImpl.java | 6 +- .../runtime/impl/EndpointReferenceBinderImpl.java | 301 +++++++++++++-------- 2 files changed, 186 insertions(+), 121 deletions(-) (limited to 'sca-java-2.x/trunk/modules/core/src/main/java/org/apache') diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java index ad7985f91b..2f18084890 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java @@ -298,7 +298,7 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen private void resolveEndpointReference() { resolve(); - boolean ok = eprBinder.bind(endpointRegistry, this); + boolean ok = eprBinder.bindRunTime(endpointRegistry, this); if (!ok) { throw new SCARuntimeException("Unable to bind " + this); } @@ -349,7 +349,9 @@ public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implemen // source interface contract for local wires this.chains = null; - setStatus(EndpointReference.NOT_CONFIGURED); + if (getStatus() == EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED){ + setStatus(EndpointReference.NOT_CONFIGURED); + } // TODO - cheating here as I fixed the RuntimeComponentService code // to call this when it resets the interface contract 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 d5b9eaaf16..f0a44eef23 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 @@ -22,15 +22,10 @@ package org.apache.tuscany.sca.core.runtime.impl; import java.util.List; import org.apache.tuscany.sca.assembly.AssemblyFactory; -import org.apache.tuscany.sca.assembly.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 @@ import org.apache.tuscany.sca.runtime.EndpointRegistry; * 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { } /** - * 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { // 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { 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 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { endpointReference.toString()); } else { problem = monitor.createProblem(this.getClass().getName(), - Messages.ASSEMBLY_VALIDATION, + "endpoint-validation-messages", Problem.Severity.WARNING, this, "ComponentReferenceTargetNotFound", @@ -202,89 +261,27 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { } 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 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 endpoints) { Endpoint matchedEndpoint = null; @@ -314,17 +311,13 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { 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 endpoints) { Problem problem = null; @@ -336,7 +329,7 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { } /** - * 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 @@ public class EndpointReferenceBinderImpl implements EndpointReferenceBinder { */ 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 endpoints = endpointRegistry.findEndpoint(endpointReference); return ! endpoints.contains(endpointReference.getTargetEndpoint()); } return false; } + /** + * ASM_5021: where a of a has @autowire=true + * and where the has a child element which + * declares a single target service, the reference is wired only to + * the single service identified by the 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; + } + } + } + } + } + } -- cgit v1.2.3