From 630599c9de5bce09c7fb1f1b657ae36164c5cc40 Mon Sep 17 00:00:00 2001 From: antelder Date: Wed, 20 Jan 2010 16:42:59 +0000 Subject: Start of making the Tuscany sca client impl work for both local or remote nodes and to be generic for any binding. Work in progress, only local invocations work presently git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@901270 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/test/scaclient/SCAClientTestCase.java | 4 +- .../java/test/scaclient/SCAClientTestCase.java | 12 ++-- .../java/test/scaclient/SCAClientTestCase.java | 2 +- .../tuscany/sca/runtime/EndpointRegistry.java | 1 + .../core/assembly/impl/EndpointRegistryImpl.java | 2 +- .../hazelcast/HazelcastEndpointRegistry.java | 35 +++++---- .../tribes/ReplicatedEndpointRegistry.java | 82 ++++++++++++---------- .../modules/sca-client-impl/META-INF/MANIFEST.MF | 5 +- .../sca/client/impl/SCAClientFactoryImpl.java | 65 +++++++++++++---- .../sca/client/impl/SCAClientProxyHandler.java | 76 ++++++++++++++++++++ 10 files changed, 205 insertions(+), 79 deletions(-) create mode 100644 sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientProxyHandler.java diff --git a/sca-java-2.x/trunk/itest/scaclient-api-jse-osgi/src/test/java/test/scaclient/SCAClientTestCase.java b/sca-java-2.x/trunk/itest/scaclient-api-jse-osgi/src/test/java/test/scaclient/SCAClientTestCase.java index 42bb229992..fbdc8c4a0b 100644 --- a/sca-java-2.x/trunk/itest/scaclient-api-jse-osgi/src/test/java/test/scaclient/SCAClientTestCase.java +++ b/sca-java-2.x/trunk/itest/scaclient-api-jse-osgi/src/test/java/test/scaclient/SCAClientTestCase.java @@ -19,6 +19,8 @@ package test.scaclient; +import java.net.URI; + import itest.HelloworldService; import junit.framework.TestCase; @@ -49,7 +51,7 @@ public class SCAClientTestCase extends TestCase { // At the moment the SCAClientFactory assumes that only one domain is active // in a JVM. So we pass in null for the domain name and get what we're given HelloworldService service = - SCAClientFactory.newInstance(null).getService(HelloworldService.class, "HelloworldComponent"); + SCAClientFactory.newInstance(URI.create("http://tuscany.apache.org/sca/1.1/domains/default")).getService(HelloworldService.class, "HelloworldComponent"); assertEquals("Hello petra", service.sayHello("petra")); } diff --git a/sca-java-2.x/trunk/itest/scaclient-api-osgi/src/test/java/test/scaclient/SCAClientTestCase.java b/sca-java-2.x/trunk/itest/scaclient-api-osgi/src/test/java/test/scaclient/SCAClientTestCase.java index c3cb8c20fa..2a2fcdf842 100644 --- a/sca-java-2.x/trunk/itest/scaclient-api-osgi/src/test/java/test/scaclient/SCAClientTestCase.java +++ b/sca-java-2.x/trunk/itest/scaclient-api-osgi/src/test/java/test/scaclient/SCAClientTestCase.java @@ -19,6 +19,8 @@ package test.scaclient; +import java.net.URI; + import itest.HelloworldService; import junit.framework.TestCase; @@ -26,6 +28,8 @@ import org.apache.tuscany.sca.node.Contribution; import org.apache.tuscany.sca.node.ContributionLocationHelper; import org.apache.tuscany.sca.node.Node; import org.apache.tuscany.sca.node.NodeFactory; +import org.oasisopen.sca.NoSuchDomainException; +import org.oasisopen.sca.NoSuchServiceException; import org.oasisopen.sca.client.SCAClientFactory; /** @@ -40,16 +44,14 @@ public class SCAClientTestCase extends TestCase { @Override protected void setUp() throws Exception { String location = ContributionLocationHelper.getContributionLocation(HelloworldService.class); - node = NodeFactory.newInstance().createNode("Helloworld.composite", new Contribution("test", "./target/classes")); + node = NodeFactory.getInstance().createNode("Helloworld.composite", new Contribution("test", "./target/classes")); System.out.println("SCA Node API ClassLoader: " + node.getClass().getClassLoader()); node.start(); } - public void testInvoke() throws Exception { - // At the moment the SCAClientFactory assumes that only one domain is active - // in a JVM. So we pass in null for the domain name and get what we're given + public void testInvoke() throws NoSuchServiceException, NoSuchDomainException { HelloworldService service = - SCAClientFactory.newInstance(null).getService(HelloworldService.class, "HelloworldComponent"); + SCAClientFactory.newInstance(URI.create("http://tuscany.apache.org/sca/1.1/domains/default")).getService(HelloworldService.class, "HelloworldComponent"); String result = service.sayHello("petra"); assertEquals("Hello petra", result); System.out.println("Result from SCAClient call = " + result); diff --git a/sca-java-2.x/trunk/itest/scaclient-api/src/test/java/test/scaclient/SCAClientTestCase.java b/sca-java-2.x/trunk/itest/scaclient-api/src/test/java/test/scaclient/SCAClientTestCase.java index e2bef08415..f4c3fd543d 100644 --- a/sca-java-2.x/trunk/itest/scaclient-api/src/test/java/test/scaclient/SCAClientTestCase.java +++ b/sca-java-2.x/trunk/itest/scaclient-api/src/test/java/test/scaclient/SCAClientTestCase.java @@ -38,7 +38,7 @@ public class SCAClientTestCase extends TestCase { @Override protected void setUp() throws Exception { - node = NodeFactory.newInstance().createNode(); + node = NodeFactory.getInstance().createNode(); node.start(); } diff --git a/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointRegistry.java b/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointRegistry.java index 630653345e..43cf9f6416 100644 --- a/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointRegistry.java +++ b/sca-java-2.x/trunk/modules/core-spi/src/main/java/org/apache/tuscany/sca/runtime/EndpointRegistry.java @@ -33,6 +33,7 @@ public interface EndpointRegistry { Endpoint getEndpoint(String uri); void updateEndpoint(String uri, Endpoint endpoint); + List findEndpoint(String uri); List findEndpoint(EndpointReference endpointReference); List getEndpoints(); diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java index aad4f924f7..4fc2ffdd30 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointRegistryImpl.java @@ -115,7 +115,7 @@ public class EndpointRegistryImpl implements EndpointRegistry, LifeCycleListener return foundEndpoints; } - protected List findEndpoint(String uri) { + public List findEndpoint(String uri) { List foundEndpoints = new ArrayList(); for (Endpoint endpoint : endpoints) { if (matches(uri, endpoint.getURI())) { diff --git a/sca-java-2.x/trunk/modules/endpoint-hazelcast/src/main/java/org/apache/tuscany/sca/endpoint/hazelcast/HazelcastEndpointRegistry.java b/sca-java-2.x/trunk/modules/endpoint-hazelcast/src/main/java/org/apache/tuscany/sca/endpoint/hazelcast/HazelcastEndpointRegistry.java index f9ec30011e..3bc9fa9f66 100644 --- a/sca-java-2.x/trunk/modules/endpoint-hazelcast/src/main/java/org/apache/tuscany/sca/endpoint/hazelcast/HazelcastEndpointRegistry.java +++ b/sca-java-2.x/trunk/modules/endpoint-hazelcast/src/main/java/org/apache/tuscany/sca/endpoint/hazelcast/HazelcastEndpointRegistry.java @@ -197,32 +197,31 @@ public class HazelcastEndpointRegistry implements EndpointRegistry, LifeCycleLis } public List findEndpoint(EndpointReference endpointReference) { - List foundEndpoints = new ArrayList(); - logger.fine("Find endpoint for reference - " + endpointReference); - if (endpointReference.getReference() != null) { Endpoint targetEndpoint = endpointReference.getTargetEndpoint(); - - for (Object v : map.values()) { - Endpoint endpoint = (Endpoint)v; - logger.fine("Matching against - " + endpoint); - if (matches(targetEndpoint.getURI(), endpoint.getURI())) { - if (!isLocal(endpoint)) { - endpoint.setRemote(true); - } - // if (!entry.isPrimary()) { - ((RuntimeEndpoint)endpoint).bind(registry, this); - // } - foundEndpoints.add(endpoint); - logger.fine("Found endpoint with matching service - " + endpoint); + return findEndpoint(targetEndpoint.getURI()); + } + return new ArrayList(); + } + + public List findEndpoint(String uri) { + List foundEndpoints = new ArrayList(); + for (Object v : map.values()) { + Endpoint endpoint = (Endpoint)v; + logger.fine("Matching against - " + endpoint); + if (matches(uri, endpoint.getURI())) { + if (!isLocal(endpoint)) { + endpoint.setRemote(true); } - // else the service name doesn't match + ((RuntimeEndpoint)endpoint).bind(registry, this); + foundEndpoints.add(endpoint); + logger.fine("Found endpoint with matching service - " + endpoint); } } - return foundEndpoints; } + private boolean isLocal(Endpoint endpoint) { return localEndpoints.contains(endpoint.getURI()); diff --git a/sca-java-2.x/trunk/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java b/sca-java-2.x/trunk/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java index 42d2eda6a3..fc16db7a74 100644 --- a/sca-java-2.x/trunk/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java +++ b/sca-java-2.x/trunk/modules/endpoint-tribes/src/main/java/org/apache/tuscany/sca/endpoint/tribes/ReplicatedEndpointRegistry.java @@ -319,55 +319,61 @@ public class ReplicatedEndpointRegistry implements EndpointRegistry, LifeCycleLi } public List findEndpoint(EndpointReference endpointReference) { - List foundEndpoints = new ArrayList(); - logger.fine("Find endpoint for reference - " + endpointReference); if (endpointReference.getReference() != null) { Endpoint targetEndpoint = endpointReference.getTargetEndpoint(); - - // in the failure case we repeat the look up after a short - // delay to take account of tribes replication delays - int repeat = FIND_REPEAT_COUNT; - - while (repeat > 0){ - for (Object v : map.values()) { - Endpoint endpoint = (Endpoint)v; - // TODO: implement more complete matching - logger.fine("Matching against - " + endpoint); - if (matches(targetEndpoint.getURI(), endpoint.getURI())) { - MapEntry entry = map.getInternal(endpoint.getURI()); - if (!isLocal(entry)) { - endpoint.setRemote(true); - } - // if (!entry.isPrimary()) { - ((RuntimeEndpoint) endpoint).bind(registry, this); - // } - foundEndpoints.add(endpoint); - logger.fine("Found endpoint with matching service - " + endpoint); - repeat = 0; - } - // else the service name doesn't match - } - - if (foundEndpoints.size() == 0) { - // the service name doesn't match any endpoints so wait a little and try - // again in case this is caused by tribes synch delays - logger.info("Repeating endpoint reference match - " + endpointReference); - repeat--; - try { - Thread.sleep(1000); - } catch(Exception ex){ - // do nothing - repeat=0; + return findEndpoint(targetEndpoint.getURI()); + } + + return new ArrayList(); + } + + public List findEndpoint(String uri) { + List foundEndpoints = new ArrayList(); + + // in the failure case we repeat the look up after a short + // delay to take account of tribes replication delays + int repeat = FIND_REPEAT_COUNT; + + while (repeat > 0){ + for (Object v : map.values()) { + Endpoint endpoint = (Endpoint)v; + // TODO: implement more complete matching + logger.fine("Matching against - " + endpoint); + if (matches(uri, endpoint.getURI())) { + MapEntry entry = map.getInternal(endpoint.getURI()); + if (!isLocal(entry)) { + endpoint.setRemote(true); } + // if (!entry.isPrimary()) { + ((RuntimeEndpoint) endpoint).bind(registry, this); + // } + foundEndpoints.add(endpoint); + logger.fine("Found endpoint with matching service - " + endpoint); + repeat = 0; + } + // else the service name doesn't match + } + + if (foundEndpoints.size() == 0) { + // the service name doesn't match any endpoints so wait a little and try + // again in case this is caused by tribes synch delays + logger.info("Repeating endpoint reference match - " + uri); + repeat--; + try { + Thread.sleep(1000); + } catch(Exception ex){ + // do nothing + repeat=0; } } } - + return foundEndpoints; } + private boolean isLocal(MapEntry entry) { return entry.getPrimary().equals(map.getChannel().getLocalMember(false)); } diff --git a/sca-java-2.x/trunk/modules/sca-client-impl/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/sca-client-impl/META-INF/MANIFEST.MF index ddfe8a0276..ae6fcb3ce3 100644 --- a/sca-java-2.x/trunk/modules/sca-client-impl/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/sca-client-impl/META-INF/MANIFEST.MF @@ -6,8 +6,11 @@ Bundle-Version: 2.0.0 Bundle-ManifestVersion: 2 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-Description: Apache Tuscany SCA Client Impl -Import-Package: org.apache.tuscany.sca.core;version="2.0.0", +Import-Package: org.apache.tuscany.sca.assembly;version="2.0.0", + org.apache.tuscany.sca.core;version="2.0.0", org.apache.tuscany.sca.node;version="2.0.0", + org.apache.tuscany.sca.node.impl;version="2.0.0", + org.apache.tuscany.sca.runtime;version="2.0.0", org.oasisopen.sca;version="2.0.0", org.oasisopen.sca.client;version="2.0.0" Bundle-SymbolicName: org.apache.tuscany.sca.client.impl diff --git a/sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientFactoryImpl.java b/sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientFactoryImpl.java index 7afc6bbe07..ef5dabeb67 100644 --- a/sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientFactoryImpl.java +++ b/sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientFactoryImpl.java @@ -19,14 +19,22 @@ package org.apache.tuscany.sca.client.impl; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; import java.net.URI; import java.util.List; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.node.Node; -import org.apache.tuscany.sca.node.NodeFinder; +import org.apache.tuscany.sca.node.NodeFactory; +import org.apache.tuscany.sca.node.impl.NodeFactoryImpl; +import org.apache.tuscany.sca.node.impl.NodeImpl; +import org.apache.tuscany.sca.runtime.DomainRegistryFactory; +import org.apache.tuscany.sca.runtime.EndpointRegistry; import org.oasisopen.sca.NoSuchDomainException; import org.oasisopen.sca.NoSuchServiceException; -import org.oasisopen.sca.ServiceUnavailableException; import org.oasisopen.sca.client.SCAClientFactory; import org.oasisopen.sca.client.SCAClientFactoryFinder; @@ -35,30 +43,59 @@ public class SCAClientFactoryImpl extends SCAClientFactory { public static void setSCAClientFactoryFinder(SCAClientFactoryFinder factoryFinder) { SCAClientFactory.factoryFinder = factoryFinder; } + + private ExtensionPointRegistry extensionsRegistry; + private EndpointRegistry endpointRegistry; + private NodeFactoryImpl nodeFactory; public SCAClientFactoryImpl(URI domainURI) throws NoSuchDomainException { super(domainURI); + + this.nodeFactory = (NodeFactoryImpl)NodeFactory.getInstance(); + this.extensionsRegistry = nodeFactory.getExtensionPoints(); + UtilityExtensionPoint utilities = extensionsRegistry.getExtensionPoint(UtilityExtensionPoint.class); + DomainRegistryFactory domainRegistryFactory = utilities.getUtility(DomainRegistryFactory.class); + this.endpointRegistry = domainRegistryFactory.getEndpointRegistry(null, getDomainURI().toString()); // TODO: shouldnt use null for reg uri + // TODO: if there is not an existing endpoint registry for the domain URI the + // this should create an endpoint registry client for the remote domain (eg hazelcast native client) + // for now just throw an exception + if (endpointRegistry == null) { + throw new NoSuchDomainException(domainURI.toString()); + } } @Override public T getService(Class serviceInterface, String serviceName) throws NoSuchServiceException, NoSuchDomainException { - URI domainURI = getDomainURI(); - if (domainURI == null) { - domainURI = URI.create(Node.DEFAULT_DOMAIN_URI); + + List eps = endpointRegistry.findEndpoint(serviceName); + if (eps == null || eps.size() < 1) { + throw new NoSuchServiceException(serviceName); } - List nodes = NodeFinder.getNodes(domainURI); - if (nodes == null || nodes.size() < 1) { - throw new NoSuchDomainException(domainURI.toString()); + Endpoint endpoint = eps.get(0); // TODO: what should be done with multiple endpoints? + + Node localNode = findLocalNode(endpoint); + if (localNode != null) { + return localNode.getService(serviceInterface, serviceName); } - for (Node n : nodes) { - try { - return n.getService(serviceInterface, serviceName); - } catch(ServiceUnavailableException e) { - // Ingore and continue + InvocationHandler handler = new SCAClientProxyHandler(serviceName, extensionsRegistry, endpointRegistry); + return (T)Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class[] {serviceInterface}, handler); + } + + private Node findLocalNode(Endpoint endpoint) { + for (Node node : nodeFactory.getNodes().values()) { + if (((NodeImpl)node).getServiceEndpoints().contains(endpoint)) { + return node; } } + return null; + } - throw new NoSuchServiceException(serviceName); + private String getDomainName() { + // TODO: parse to extract just the domain name from the uri + if (getDomainURI().getHost() != null) { + return getDomainURI().getHost(); + } + return getDomainURI().toString(); } } diff --git a/sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientProxyHandler.java b/sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientProxyHandler.java new file mode 100644 index 0000000000..c5913070e8 --- /dev/null +++ b/sca-java-2.x/trunk/modules/sca-client-impl/src/main/java/org/apache/tuscany/sca/client/impl/SCAClientProxyHandler.java @@ -0,0 +1,76 @@ +/* + * 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. + */ + +package org.apache.tuscany.sca.client.impl; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.List; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.runtime.EndpointRegistry; +import org.oasisopen.sca.NoSuchServiceException; + +/** + * TODO: What this wants is a way to create a generic invoker for an arbitrary binding + * that could mean extending the BindingProvider API to include something like a + * createClient method which creates an Invoker for an Endpoint + */ +public class SCAClientProxyHandler implements InvocationHandler { + + protected EndpointRegistry endpointRegistry; + protected EndpointReference endpointReference; + protected String serviceName; + + public SCAClientProxyHandler(String serviceName, ExtensionPointRegistry extensionsRegistry, EndpointRegistry endpointRegistry) { + this.endpointRegistry = endpointRegistry; + this.serviceName = serviceName; + +// RMIHostExtensionPoint rmiHosts = extensionsRegistry.getExtensionPoint(RMIHostExtensionPoint.class); +// this.rmiHost = new ExtensibleRMIHost(rmiHosts); + + FactoryExtensionPoint factories = extensionsRegistry.getExtensionPoint(FactoryExtensionPoint.class); + AssemblyFactory assemblyFactory = factories.getFactory(AssemblyFactory.class); + + this.endpointReference = assemblyFactory.createEndpointReference(); + endpointReference.setReference(assemblyFactory.createComponentReference()); + Endpoint targetEndpoint = assemblyFactory.createEndpoint(); + targetEndpoint.setURI(serviceName); + endpointReference.setTargetEndpoint(targetEndpoint); + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + List endpoints = endpointRegistry.findEndpoint(endpointReference); + if (endpoints.size() <1 ) { + throw new NoSuchServiceException(serviceName); + } + + String uri = endpoints.get(0).getBinding().getURI(); +// RMIBindingInvoker invoker = new RMIBindingInvoker(rmiHost, uri, method); +// +// return invoker.invokeTarget(args); + return null; + } + +} -- cgit v1.2.3