From 08112844bcf38cb003d8865fe1a73c17836d269d Mon Sep 17 00:00:00 2001 From: slaws Date: Thu, 27 Aug 2009 17:52:39 +0000 Subject: Add policy matching to the endpoint builder and prepare for problems to be raised at runtime and at build time. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@808552 13f79535-47bb-0310-9956-ffa450edef68 --- .../assembly/builder/EndpointReferenceBuilder.java | 3 +- .../sca/core/assembly/impl/RuntimeWireImpl.java | 8 +- .../core/context/impl/ComponentContextImpl.java | 8 +- .../impl/EndpointReferenceBuilderImpl.java | 207 ++++++++++++++++----- .../endpoint-validation-messages.properties | 22 +++ 5 files changed, 202 insertions(+), 46 deletions(-) create mode 100644 java/sca/modules/endpoint/src/main/resources/endpoint-validation-messages.properties diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java index 1954e82168..7c56f965a0 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/EndpointReferenceBuilder.java @@ -21,6 +21,7 @@ package org.apache.tuscany.sca.assembly.builder; import org.apache.tuscany.sca.assembly.Composite; import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.monitor.Problem; /** * A builder that handles the configuration of endpoint references @@ -47,6 +48,6 @@ public interface EndpointReferenceBuilder { * @param endpointReference * @param monitor */ - void runtimeBuild(EndpointReference endpointReference); + Problem runtimeBuild(EndpointReference endpointReference); } diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java index 7dd9eb993a..b31a8e7d1a 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeWireImpl.java @@ -52,6 +52,7 @@ 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.monitor.Problem; import org.apache.tuscany.sca.provider.BindingProviderFactory; import org.apache.tuscany.sca.provider.ImplementationProvider; import org.apache.tuscany.sca.provider.PolicyProvider; @@ -69,6 +70,7 @@ 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; +import org.oasisopen.sca.SCARuntimeException; import org.oasisopen.sca.ServiceRuntimeException; /** @@ -329,7 +331,11 @@ public class RuntimeWireImpl implements RuntimeWire { * is first used */ private void resolveEndpointReference(){ - endpointReferenceBuilder.runtimeBuild(endpointReference); + Problem problem = endpointReferenceBuilder.runtimeBuild(endpointReference); + + if (problem != null){ + throw new SCARuntimeException(problem.toString()); + } // set the endpoint based on the resolved endpoint endpoint = endpointReference.getTargetEndpoint(); diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java index 7ad4db79dc..21f907608c 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/impl/ComponentContextImpl.java @@ -56,10 +56,12 @@ import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentReference; import org.apache.tuscany.sca.runtime.RuntimeComponentService; import org.oasisopen.sca.RequestContext; +import org.oasisopen.sca.SCARuntimeException; import org.oasisopen.sca.ServiceReference; import org.oasisopen.sca.ServiceRuntimeException; @@ -361,7 +363,11 @@ public class ComponentContextImpl implements ComponentContextExt { componentReference.getEndpointReferences().add(endpointReference); // do binding matching - endpointReferenceBuilder.runtimeBuild(endpointReference); + Problem problem = endpointReferenceBuilder.runtimeBuild(endpointReference); + + if (problem != null){ + throw new SCARuntimeException(problem.toString()); + } return componentReference; } diff --git a/java/sca/modules/endpoint/src/main/java/org/apache/tuscany/sca/endpoint/impl/EndpointReferenceBuilderImpl.java b/java/sca/modules/endpoint/src/main/java/org/apache/tuscany/sca/endpoint/impl/EndpointReferenceBuilderImpl.java index 49b7c4c7b4..8ad3b471e1 100644 --- a/java/sca/modules/endpoint/src/main/java/org/apache/tuscany/sca/endpoint/impl/EndpointReferenceBuilderImpl.java +++ b/java/sca/modules/endpoint/src/main/java/org/apache/tuscany/sca/endpoint/impl/EndpointReferenceBuilderImpl.java @@ -38,8 +38,10 @@ import org.apache.tuscany.sca.core.UtilityExtensionPoint; 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.MonitorFactory; import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.Intent; import org.apache.tuscany.sca.policy.PolicySet; import org.apache.tuscany.sca.policy.PolicySubject; import org.apache.tuscany.sca.runtime.EndpointRegistry; @@ -60,6 +62,7 @@ public class EndpointReferenceBuilderImpl implements EndpointReferenceBuilder { protected AssemblyFactory assemblyFactory; protected InterfaceContractMapper interfaceContractMapper; protected EndpointRegistry endpointRegistry; + private Monitor monitor; public EndpointReferenceBuilderImpl(ExtensionPointRegistry extensionPoints) { @@ -70,8 +73,9 @@ public class EndpointReferenceBuilderImpl implements EndpointReferenceBuilder { UtilityExtensionPoint utils = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); this.interfaceContractMapper = utils.getUtility(InterfaceContractMapper.class); - this.endpointRegistry = utils.getUtility(EndpointRegistry.class); + MonitorFactory monitorFactory = utils.getUtility(MonitorFactory.class); + monitor = monitorFactory.createMonitor(); } /** @@ -94,7 +98,9 @@ public class EndpointReferenceBuilderImpl implements EndpointReferenceBuilder { * @param endpoint * @param monitor */ - public void runtimeBuild(EndpointReference endpointReference) { + public Problem runtimeBuild(EndpointReference endpointReference) { + + Problem problem = null; if ( endpointReference.getStatus() == EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED || endpointReference.getStatus() == EndpointReference.RESOLVED_BINDING ) { @@ -103,25 +109,24 @@ public class EndpointReferenceBuilderImpl implements EndpointReferenceBuilder { // a remote binding // still need to check that the callback endpoint is set correctly - if ((endpointReference.getCallbackEndpoint() != null) && - (endpointReference.getCallbackEndpoint().isUnresolved() == false)){ - return; - } - - selectCallbackBinding(endpointReference); - + 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 - - // TODO - EPR - endpoint selection - // just use the first one - endpointReference.setTargetEndpoint(endpointReference.getTargetEndpoint().getService().getEndpoints().get(0)); + // target URL and/or the policies have yet to be matched. - selectForwardBinding(endpointReference); + problem = selectForwardEndpoint(endpointReference, + endpointReference.getTargetEndpoint().getService().getEndpoints()); - selectCallbackBinding(endpointReference); + 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){ @@ -131,56 +136,172 @@ public class EndpointReferenceBuilderImpl implements EndpointReferenceBuilder { List endpoints = endpointRegistry.findEndpoint(endpointReference); if (endpoints.size() == 0) { - throw new SCARuntimeException("No endpoints found for EndpointReference " + endpointReference.toString()); + problem = monitor.createProblem(this.getClass().getName(), + "endpoint-validation-messages", + Problem.Severity.ERROR, + this, + "NoEndpointsFound", + endpointReference.toString()); } - - // TODO - EPR - endpoint selection - // just use the first one - endpointReference.setTargetEndpoint(endpoints.get(0)); - selectForwardBinding(endpointReference); + problem = selectForwardEndpoint(endpointReference, + endpoints); - selectCallbackBinding(endpointReference); - - } else { - // endpointReference.getStatus() == EndpointReference.NOT_CONFIGURED - // An error as we shouldn't get here - throw new SCARuntimeException("EndpointReference can't be resolved " + endpointReference.toString()); + if (problem == null && hasCallback(endpointReference)){ + problem = selectCallbackEndpoint(endpointReference, + endpointReference.getReference().getCallbackService().getEndpoints()); + } + } + + if (problem != null){ + return problem; } if (endpointReference.getStatus() != EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED && endpointReference.getStatus() != EndpointReference.RESOLVED_BINDING){ - throw new SCARuntimeException("EndpointReference can't be resolved " + endpointReference.toString()); + problem = monitor.createProblem(this.getClass().getName(), + "endpoint-validation-messages", + Problem.Severity.ERROR, + this, + "EndpointReferenceCantBeMatched", + endpointReference.toString()); } + + return problem; } - private void selectForwardBinding(EndpointReference endpointReference) { - - Endpoint endpoint = endpointReference.getTargetEndpoint(); + private Problem selectForwardEndpoint(EndpointReference endpointReference, List endpoints) { + + Endpoint matchedEndpoint = null; + if (endpointReference.getReference().getName().startsWith("$self$.")){ + // just select the first one and don't do any policy matching + matchedEndpoint = endpoints.get(0); + } else { + // find the first endpoint that matches this endpoint reference + for (Endpoint endpoint : endpoints){ + if (haveMatchingPolicy(endpointReference, endpoint)){ + matchedEndpoint = endpoint; + } + } + } + + if (matchedEndpoint == null){ + return null; + } + + endpointReference.setTargetEndpoint(matchedEndpoint); endpointReference.setBinding(endpointReference.getTargetEndpoint().getBinding()); endpointReference.setStatus(EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED); endpointReference.setUnresolved(false); - return; + return null; } - - private void selectCallbackBinding(EndpointReference endpointReference) { - - // if no callback on the interface or we are creating a self reference do nothing + + private boolean hasCallback(EndpointReference endpointReference){ if (endpointReference.getReference().getInterfaceContract() == null || endpointReference.getReference().getInterfaceContract().getCallbackInterface() == null || endpointReference.getReference().getName().startsWith("$self$.")){ - return; + return false; + } else { + return true; } + } - Endpoint endpoint = endpointReference.getTargetEndpoint(); + private Problem selectCallbackEndpoint(EndpointReference endpointReference, List endpoints) { - List callbackEndpoints = endpointReference.getReference().getCallbackService().getEndpoints(); + Problem problem = null; - endpointReference.setCallbackEndpoint(callbackEndpoints.get(0)); - endpointReference.setStatus(EndpointReference.WIRED_TARGET_FOUND_AND_MATCHED); - endpointReference.setUnresolved(false); + // find the first callback endpoint that matches a callback endpoint reference + // at the service + Endpoint matchedEndpoint = null; + match: + for ( EndpointReference callbackEndpointReference : endpointReference.getTargetEndpoint().getCallbackEndpointReferences()){ + for (Endpoint endpoint : endpoints){ + if (haveMatchingPolicy(callbackEndpointReference, endpoint)){ + matchedEndpoint = endpoint; + break match; + } + } + } + + if (matchedEndpoint == null){ + return null; + } + + endpointReference.setCallbackEndpoint(matchedEndpoint); + + return problem; + } + + private boolean haveMatchingPolicy(EndpointReference endpointReference, Endpoint endpoint){ + + // if no policy sets or intents are present then they match + if ((endpointReference.getRequiredIntents().size() == 0) && + (endpoint.getRequiredIntents().size() == 0) && + (endpointReference.getPolicySets().size() == 0) && + (endpoint.getPolicySets().size() == 0)) { + return true; + } + + // if there are different numbers of intents + // then they don't match + if (endpointReference.getRequiredIntents().size() != + endpoint.getRequiredIntents().size()) { + return false; + } + + // if there are different numbers of policy sets + // then they don't match + if (endpointReference.getPolicySets().size() != + endpoint.getPolicySets().size()) { + return false; + } + + // check intents for compatibility + for(Intent intentEPR : endpointReference.getRequiredIntents()){ + boolean matched = false; + for (Intent intentEP : endpoint.getRequiredIntents()){ + if (intentEPR.getName().equals(intentEP.getName())){ + matched = true; + break; + } + } + if (matched == false){ + return false; + } + } + + // check policy sets for compatibility. The list of policy sets + // may be a subset of the list of intents as some of the intents + // may be directly provided. We can't just rely on intent compatibility + // as different policy sets might have been attached at each end to + // satisfy the listed intents + + // if all of the policy sets on the endpoint reference match a + // policy set on the endpoint then they match + for(PolicySet policySetEPR : endpointReference.getPolicySets()){ + boolean matched = false; + for (PolicySet policySetEP : endpoint.getPolicySets()){ + // find if there is a policy set with the same name + if (policySetEPR.getName().equals(policySetEP.getName())){ + matched = true; + break; + } + // find if the policies inside the policy set match the + // policies inside a policy set on the endpoint + + // TODO - need a policy specific matcher to do this + // so need a new extension point + + } + + if (matched == false){ + return false; + } + } + + return true; } } diff --git a/java/sca/modules/endpoint/src/main/resources/endpoint-validation-messages.properties b/java/sca/modules/endpoint/src/main/resources/endpoint-validation-messages.properties new file mode 100644 index 0000000000..7be0f2b4a2 --- /dev/null +++ b/java/sca/modules/endpoint/src/main/resources/endpoint-validation-messages.properties @@ -0,0 +1,22 @@ +# +# +# 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. +# +# +NoEndpointsFound = No endpoints found in the domain that match the reference {0} +EndpointReferenceCantBeMatched = = Unable to match the endpoint reference {0} with the policy of the service to which it refers. -- cgit v1.2.3