From 13b7f97dd44734f792038d514a06bb276c7ba0dc Mon Sep 17 00:00:00 2001 From: wjaniszewski Date: Fri, 1 Aug 2008 22:27:33 +0000 Subject: 1. SCA default binding over CORBA - now transient name server is beeing created automatically for localhost service bindings. 2. Code cleanup git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@681871 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca/test/corba/ScenarioFourTestCase.java | 39 ++-- .../test/corba/types/ScenarioFourException.java | 3 + .../src/test/resources/ScenarioFour.composite | 17 +- .../sca/binding/corba/impl/TuscanyServant.java | 45 ----- java/sca/modules/binding-sca-corba/pom.xml | 24 +-- .../sca/corba/impl/CorbaSCAInvocationProxy.java | 4 +- .../corba/impl/CorbaSCAServiceBindingProvider.java | 20 +- .../sca/binding/sca/corba/impl/SocketUtil.java | 225 +++++++++++++++++++++ .../sca/corba/impl/WrappedSCAException.java | 13 ++ .../sca/host/corba/jdk/DefaultCorbaHost.java | 55 ++++- .../corba/testing/DefaultCorbaHostTestCase.java | 38 ++++ .../tuscany/sca/host/corba/jee/JEECorbaHost.java | 8 + .../apache/tuscany/sca/host/corba/CorbaHost.java | 21 +- .../sca/host/corba/ExtensibleCorbaHost.java | 9 +- 14 files changed, 421 insertions(+), 100 deletions(-) delete mode 100644 java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/TuscanyServant.java create mode 100755 java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/SocketUtil.java diff --git a/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/ScenarioFourTestCase.java b/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/ScenarioFourTestCase.java index 7ab5ca1e14..2f3e421392 100644 --- a/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/ScenarioFourTestCase.java +++ b/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/ScenarioFourTestCase.java @@ -23,8 +23,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import junit.framework.Assert; -import org.apache.tuscany.sca.host.corba.naming.TransientNameServer; -import org.apache.tuscany.sca.host.corba.naming.TransientNameService; import org.apache.tuscany.sca.host.embedded.SCADomain; import org.apache.tuscany.sca.test.corba.scenariofour.ScenarioFourFactory; import org.apache.tuscany.sca.test.corba.scenariofour.ScenarioFourSdo; @@ -43,30 +41,16 @@ import org.junit.Test; public class ScenarioFourTestCase { // note that those values are also used in resources/*.composite file - private static int ORB_INITIAL_PORT = 5060; private static SCADomain domain; - private static TransientNameServer server; private static ScenarioFourComponent scenarioFourComponent; private static ScenarioFour scenarioFour; /** - * Sets up name service, creates and registers traditional CORBA service, - * obtains SCADomain + * Initial configuration */ @BeforeClass public static void setUp() { try { - try { - server = - new TransientNameServer("localhost", ORB_INITIAL_PORT, TransientNameService.DEFAULT_SERVICE_NAME); - Thread t = server.start(); - if (t == null) { - Assert.fail("The naming server cannot be started"); - } - } catch (Throwable e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } // obtain domain domain = SCADomain.newInstance("ScenarioFour.composite"); scenarioFourComponent = domain.getService(ScenarioFourComponent.class, "ScenarioFour"); @@ -77,11 +61,11 @@ public class ScenarioFourTestCase { } /** - * Kills previously spawned name service. + * Test cleanup */ @AfterClass public static void tearDown() { - server.stop(); + // do nothing } /** @@ -133,5 +117,20 @@ public class ScenarioFourTestCase { e.printStackTrace(); fail(); } - } + } + + /** + * Tests reusing local name server with multiple bindings + */ + @Test + public void test_nameServerReuse() { + try { + ScenarioFour scenarioFour = domain.getService(ScenarioFourComponent.class, "ScenarioFourReuse").getScenarioFour(); + ScenarioFourStruct struct = new ScenarioFourStruct(); + scenarioFour.setStruct(struct); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + } } diff --git a/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/types/ScenarioFourException.java b/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/types/ScenarioFourException.java index 1afda33e35..23b29be7f1 100644 --- a/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/types/ScenarioFourException.java +++ b/java/sca/itest/corba/src/test/java/org/apache/tuscany/sca/test/corba/types/ScenarioFourException.java @@ -19,6 +19,9 @@ package org.apache.tuscany.sca.test.corba.types; +/** + * Exception for ScenarioFour tests + */ public class ScenarioFourException extends Exception { public static final String DEFAULT_CONTENT = "Test"; diff --git a/java/sca/itest/corba/src/test/resources/ScenarioFour.composite b/java/sca/itest/corba/src/test/resources/ScenarioFour.composite index c13bf7fd79..01d7e2314a 100644 --- a/java/sca/itest/corba/src/test/resources/ScenarioFour.composite +++ b/java/sca/itest/corba/src/test/resources/ScenarioFour.composite @@ -30,13 +30,26 @@ - + - + + + + + + + + + + + + + + diff --git a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/TuscanyServant.java b/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/TuscanyServant.java deleted file mode 100644 index 2be169cdcb..0000000000 --- a/java/sca/modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/impl/TuscanyServant.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.binding.corba.impl; - -import org.omg.CORBA.ORB; -import org.omg.CORBA.ServerRequest; -import org.omg.PortableServer.DynamicImplementation; -import org.omg.PortableServer.POA; - -/** - * This is the CORBA DSI servant that dispatches CORBA requests to SCA components - * - * @version $Rev$ $Date$ - */ -public class TuscanyServant extends DynamicImplementation { - private ORB orb; - - @Override - public void invoke(ServerRequest request) { - } - - @Override - public String[] _all_interfaces(POA poa, byte[] objectId) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/java/sca/modules/binding-sca-corba/pom.xml b/java/sca/modules/binding-sca-corba/pom.xml index 37e7914254..15fb487eee 100644 --- a/java/sca/modules/binding-sca-corba/pom.xml +++ b/java/sca/modules/binding-sca-corba/pom.xml @@ -71,29 +71,11 @@ 1.4-SNAPSHOT - - org.apache.tuscany.sca - tuscany-databinding-axiom - 1.4-SNAPSHOT - - - org.apache.tuscany.sca diff --git a/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAInvocationProxy.java b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAInvocationProxy.java index f20b027644..69b0954d03 100644 --- a/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAInvocationProxy.java +++ b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAInvocationProxy.java @@ -75,9 +75,7 @@ public class CorbaSCAInvocationProxy implements InvocationProxy { break; } } - if (componentOperation == null) { - // TODO: throw an exception - no such operation - } else { + if (componentOperation != null) { Message msg = messageFactory.createMessage(); msg.setOperation(componentOperation); Object[] args = new Object[1]; diff --git a/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAServiceBindingProvider.java b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAServiceBindingProvider.java index 1dabefc9f7..1f96327bf6 100644 --- a/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAServiceBindingProvider.java +++ b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/CorbaSCAServiceBindingProvider.java @@ -28,6 +28,7 @@ import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory; import org.apache.tuscany.sca.binding.ws.wsdlgen.BindingWSDLGenerator; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.host.corba.CorbaHost; +import org.apache.tuscany.sca.host.corba.CorbanameURL; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.provider.ServiceBindingProvider; @@ -35,7 +36,6 @@ import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentService; import org.osoa.sca.ServiceRuntimeException; - /** * Service binding provider for SCA default binding over CORBA binding */ @@ -47,6 +47,8 @@ public class CorbaSCAServiceBindingProvider implements ServiceBindingProvider { private DynaCorbaServant servant; private MessageFactory messageFactory; private InterfaceContract wsdlInterfaceContract; + private boolean isLocalhost; + private int bindingPort; public CorbaSCAServiceBindingProvider(SCABinding binding, CorbaHost host, @@ -57,8 +59,12 @@ public class CorbaSCAServiceBindingProvider implements ServiceBindingProvider { this.host = host; this.service = service; - messageFactory = extensions.getExtensionPoint(MessageFactory.class); + CorbanameURL details = new CorbanameURL(binding.getURI()); + isLocalhost = SocketUtil.isLocalhost(details.getHost()); + bindingPort = details.getPort(); + messageFactory = extensions.getExtensionPoint(MessageFactory.class); + WebServiceBindingFactory wsFactory = extensions.getExtensionPoint(WebServiceBindingFactory.class); WebServiceBinding wsBinding = wsFactory.createWebServiceBinding(); BindingWSDLGenerator.generateWSDL(component, service, wsBinding, extensions, null); @@ -76,8 +82,13 @@ public class CorbaSCAServiceBindingProvider implements ServiceBindingProvider { public void start() { try { - InvocationProxy proxy = new CorbaSCAInvocationProxy(service.getRuntimeWire(binding), service.getInterfaceContract().getInterface(), messageFactory); + InvocationProxy proxy = + new CorbaSCAInvocationProxy(service.getRuntimeWire(binding), service.getInterfaceContract() + .getInterface(), messageFactory); servant = new DynaCorbaServant(proxy, "IDL:org/apache/tuscany/sca/binding/sca/corba/Service:1.0"); + if (isLocalhost) { + host.createLocalNameServer(bindingPort); + } host.registerServant(binding.getURI(), servant); } catch (Exception e) { throw new ServiceRuntimeException(e); @@ -87,6 +98,9 @@ public class CorbaSCAServiceBindingProvider implements ServiceBindingProvider { public void stop() { try { host.unregisterServant(binding.getURI()); + if (isLocalhost) { + host.releaseLocalNameServer(bindingPort); + } } catch (Exception e) { throw new ServiceRuntimeException(e); } diff --git a/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/SocketUtil.java b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/SocketUtil.java new file mode 100755 index 0000000000..6f4b4b9a9b --- /dev/null +++ b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/SocketUtil.java @@ -0,0 +1,225 @@ +/* + * 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.binding.sca.corba.impl; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * Class partially copied from eclipse wst project + * (http://repo1.maven.org/maven2/org/eclipse/wst/server/core/1.0.205-v20070829b/). + * Finally we should use jar from maven dependency. Problem described in + * http://www.fornax-platform.org/cp/display/fornax/2.+Hello+World+Tutorial+(CSC)?replyToComment=2098#comment-2098 + * needs to be fixed. + */ +public class SocketUtil { + + protected static final Object lock = new Object(); + + private static Set localHostCache; + private static Set notLocalHostCache = new HashSet(); + private static Map threadMap = new HashMap(); + + private static Set addressCache; + + static class CacheThread extends Thread { + private Set currentAddresses; + private Set addressList; + private String host; + private Set nonAddressList; + private Map threadMap2; + + public CacheThread(String host, + Set currentAddresses, + Set addressList, + Set nonAddressList, + Map threadMap2) { + super("Caching localhost information"); + this.host = host; + this.currentAddresses = currentAddresses; + this.addressList = addressList; + this.nonAddressList = nonAddressList; + this.threadMap2 = threadMap2; + } + + public void run() { + if (currentAddresses != null) { + Iterator iter2 = currentAddresses.iterator(); + while (iter2.hasNext()) { + InetAddress addr = (InetAddress)iter2.next(); + String hostname = addr.getHostName(); + String hostname2 = addr.getCanonicalHostName(); + synchronized (lock) { + if (hostname != null && !addressList.contains(hostname)) + addressList.add(hostname); + if (hostname2 != null && !addressList.contains(hostname2)) + addressList.add(hostname2); + } + } + } + + try { + InetAddress[] addrs = InetAddress.getAllByName(host); + int length = addrs.length; + for (int j = 0; j < length; j++) { + InetAddress addr = addrs[0]; + String hostname = addr.getHostName(); + String hostname2 = addr.getCanonicalHostName(); + synchronized (lock) { + if (addr.isLoopbackAddress()) { + if (hostname != null && !addressList.contains(hostname)) + addressList.add(hostname); + if (hostname2 != null && !addressList.contains(hostname2)) + addressList.add(hostname2); + } else { + if (hostname != null && !nonAddressList.contains(hostname)) + nonAddressList.add(hostname); + if (hostname2 != null && !nonAddressList.contains(hostname2)) + nonAddressList.add(hostname2); + } + } + } + } catch (UnknownHostException e) { + synchronized (lock) { + if (host != null && !nonAddressList.contains(host)) + nonAddressList.add(host); + } + } + synchronized (lock) { + threadMap2.remove(host); + } + } + } + + public static boolean isLocalhost(final String host) { + if (host == null || host.equals("")) + return false; + + if ("localhost".equals(host) || "127.0.0.1".equals(host)) + return true; + + // check simple cases + try { + InetAddress localHostaddr = InetAddress.getLocalHost(); + if (localHostaddr.getHostName().equals(host) || host.equals(localHostaddr.getCanonicalHostName()) + || localHostaddr.getHostAddress().equals(host)) + return true; + } catch (Exception e) { + + } + + // check for current thread and wait if necessary + boolean currentThread = false; + try { + Thread t = null; + synchronized (lock) { + t = threadMap.get(host); + } + if (t != null && t.isAlive()) { + currentThread = true; + t.join(30); + } + } catch (Exception e) { + + } + + // check if cache is still ok + boolean refreshedCache = false; + try { + // get network interfaces + final Set currentAddresses = new HashSet(); + currentAddresses.add(InetAddress.getLocalHost()); + Enumeration nis = NetworkInterface.getNetworkInterfaces(); + while (nis.hasMoreElements()) { + NetworkInterface inter = (NetworkInterface)nis.nextElement(); + Enumeration ias = inter.getInetAddresses(); + while (ias.hasMoreElements()) + currentAddresses.add(ias.nextElement()); + } + + // check if cache is empty or old and refill it if necessary + if (addressCache == null || !addressCache.containsAll(currentAddresses) + || !currentAddresses.containsAll(addressCache)) { + CacheThread cacheThread = null; + refreshedCache = true; + + synchronized (lock) { + addressCache = currentAddresses; + notLocalHostCache = new HashSet(); + localHostCache = new HashSet(currentAddresses.size() * 3); + + Iterator iter = currentAddresses.iterator(); + while (iter.hasNext()) { + InetAddress addr = (InetAddress)iter.next(); + String a = addr.getHostAddress(); + if (a != null && !localHostCache.contains(a)) + localHostCache.add(a); + } + + cacheThread = new CacheThread(host, currentAddresses, localHostCache, notLocalHostCache, threadMap); + threadMap.put(host, cacheThread); + cacheThread.setDaemon(true); + cacheThread.setPriority(Thread.NORM_PRIORITY - 1); + cacheThread.start(); + } + cacheThread.join(200); + } + } catch (Exception e) { + } + + synchronized (lock) { + if (localHostCache.contains(host)) + return true; + if (notLocalHostCache.contains(host)) + return false; + } + + // if the cache hasn't been cleared, maybe we still need to lookup the + // host + if (!refreshedCache && !currentThread) { + try { + CacheThread cacheThread = null; + synchronized (lock) { + cacheThread = new CacheThread(host, null, localHostCache, notLocalHostCache, threadMap); + threadMap.put(host, cacheThread); + cacheThread.setDaemon(true); + cacheThread.setPriority(Thread.NORM_PRIORITY - 1); + cacheThread.start(); + } + cacheThread.join(75); + + synchronized (lock) { + if (localHostCache.contains(host)) + return true; + } + } catch (Exception e) { + } + } + return false; + } + +} diff --git a/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/WrappedSCAException.java b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/WrappedSCAException.java index c8e06ecbc1..128d5ef159 100644 --- a/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/WrappedSCAException.java +++ b/java/sca/modules/binding-sca-corba/src/main/java/org/apache/tuscany/sca/binding/sca/corba/impl/WrappedSCAException.java @@ -19,15 +19,28 @@ package org.apache.tuscany.sca.binding.sca.corba.impl; +/** + * Exception holder for SCA default binding over CORBA. Holds fault message in + * XML + */ public class WrappedSCAException extends Exception { private static final long serialVersionUID = 1L; public String fault; + /** + * Creates exception holder with null fault message. This no argument + * constructor is needed by CORBA binding. + */ public WrappedSCAException() { } + /** + * Creates exception holder with fault message + * + * @param fault XML fault message + */ public WrappedSCAException(String fault) { this.fault = fault; } diff --git a/java/sca/modules/host-corba-jdk/src/main/java/org/apache/tuscany/sca/host/corba/jdk/DefaultCorbaHost.java b/java/sca/modules/host-corba-jdk/src/main/java/org/apache/tuscany/sca/host/corba/jdk/DefaultCorbaHost.java index 7e78607fd9..fc7889f5e9 100644 --- a/java/sca/modules/host-corba-jdk/src/main/java/org/apache/tuscany/sca/host/corba/jdk/DefaultCorbaHost.java +++ b/java/sca/modules/host-corba-jdk/src/main/java/org/apache/tuscany/sca/host/corba/jdk/DefaultCorbaHost.java @@ -29,6 +29,8 @@ import org.apache.tuscany.sca.host.corba.CorbaHost; import org.apache.tuscany.sca.host.corba.CorbaHostException; import org.apache.tuscany.sca.host.corba.CorbaHostUtils; import org.apache.tuscany.sca.host.corba.CorbanameURL; +import org.apache.tuscany.sca.host.corba.naming.TransientNameServer; +import org.apache.tuscany.sca.host.corba.naming.TransientNameService; import org.omg.CORBA.ORB; import org.omg.CORBA.Object; import org.omg.CosNaming.NameComponent; @@ -46,6 +48,8 @@ public class DefaultCorbaHost implements CorbaHost { private static final Logger logger = Logger.getLogger(DefaultCorbaHost.class.getName()); private Map orbs = new ConcurrentHashMap(); + private Map localServers = new ConcurrentHashMap(); + private Map clientsCount = new ConcurrentHashMap(); private void validatePort(int port) throws IllegalArgumentException { if (port < 1) { @@ -83,7 +87,8 @@ public class DefaultCorbaHost implements CorbaHost { namingCtx = namingCtx.bind_new_context(path); } } - NameComponent finalName = new NameComponent(details.getNamePath().get(details.getNamePath().size() - 1), ""); + NameComponent finalName = + new NameComponent(details.getNamePath().get(details.getNamePath().size() - 1), ""); try { namingCtx.resolve(new NameComponent[] {finalName}); // no exception means that some object is already registered @@ -109,7 +114,7 @@ public class DefaultCorbaHost implements CorbaHost { handleException(e); } } - + public Object lookup(String uri) throws CorbaHostException { Object result = null; try { @@ -118,7 +123,6 @@ public class DefaultCorbaHost implements CorbaHost { NamingContextExt context = getNamingContext(orb, url.getNameService()); result = context.resolve_str(url.getName()); } catch (Exception e) { - // e.printStackTrace(); handleException(e); } if (result == null) { @@ -177,4 +181,49 @@ public class DefaultCorbaHost implements CorbaHost { } } + /** + * Starts transient name server under given port. If TNS was previously + * spawned it increments clients counter. + */ + synchronized public void createLocalNameServer(int port) throws CorbaHostException { + int useCount = clientsCount.containsKey(port) ? clientsCount.get(port) : 0; + // no server previously spawned + if (useCount == 0) { + TransientNameServer server = + new TransientNameServer("localhost", port, TransientNameService.DEFAULT_SERVICE_NAME); + Thread thread = server.start(); + if (thread == null) { + throw new CorbaHostException("TransientNameServer couldn't be started"); + } else { + localServers.put(port, server); + } + } + clientsCount.put(port, ++useCount); + } + + /** + * Stops transient name server if there is only one client left using such + * TNS. Decrements clients counter if TNS is used by 2 or more clients. + */ + synchronized public void releaseLocalNameServer(int port) throws CorbaHostException { + int useCount = clientsCount.containsKey(port) ? clientsCount.get(port) : 0; + if (useCount == 1) { + // last client executed stop, cleaning up + TransientNameServer server = localServers.get(port); + if (server != null) { + server.stop(); + clientsCount.remove(port); + localServers.remove(port); + } else { + // FIXME: should we throw exception when expecting not null + // server object? + } + } else if (useCount > 1) { + clientsCount.put(port, --useCount); + } else { + // ignoring request to stop non existing name server + } + + } + } diff --git a/java/sca/modules/host-corba-jdk/src/test/java/org/apache/tuscany/sca/host/corba/testing/DefaultCorbaHostTestCase.java b/java/sca/modules/host-corba-jdk/src/test/java/org/apache/tuscany/sca/host/corba/testing/DefaultCorbaHostTestCase.java index 1a9894ae05..07e61fc175 100644 --- a/java/sca/modules/host-corba-jdk/src/test/java/org/apache/tuscany/sca/host/corba/testing/DefaultCorbaHostTestCase.java +++ b/java/sca/modules/host-corba-jdk/src/test/java/org/apache/tuscany/sca/host/corba/testing/DefaultCorbaHostTestCase.java @@ -25,6 +25,7 @@ import static junit.framework.Assert.fail; import java.net.ConnectException; import java.net.Socket; +import java.net.SocketException; import org.apache.tuscany.sca.host.corba.CorbaHost; import org.apache.tuscany.sca.host.corba.CorbaHostException; @@ -220,6 +221,9 @@ public class DefaultCorbaHostTestCase { } } + /** + * + */ @Test public void test_ensureORBStopped() { try { @@ -242,4 +246,38 @@ public class DefaultCorbaHostTestCase { } } } + + /** + * Test for creating and releasing local name server + */ + @Test + public void test_localNameServer() { + int testPort = 5070; + try { + host.createLocalNameServer(testPort); + host.createLocalNameServer(testPort); + host.createLocalNameServer(testPort); + // make test connection to name server + Socket socket = new Socket("localhost", testPort); + socket.close(); + // and stop server + host.releaseLocalNameServer(testPort); + host.releaseLocalNameServer(testPort); + // after releasing 2 clients 3rd should still hold the server + socket = new Socket("localhost", testPort); + socket.close(); + host.releaseLocalNameServer(testPort); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + try { + // previously made 3rd stop so there should be no name server under + // this port + new Socket("localhost", testPort); + fail(); + } catch (Exception e) { + assertTrue(e instanceof SocketException); + } + } } diff --git a/java/sca/modules/host-corba-jee/src/main/java/org/apache/tuscany/sca/host/corba/jee/JEECorbaHost.java b/java/sca/modules/host-corba-jee/src/main/java/org/apache/tuscany/sca/host/corba/jee/JEECorbaHost.java index c2f903961b..561b9abfba 100644 --- a/java/sca/modules/host-corba-jee/src/main/java/org/apache/tuscany/sca/host/corba/jee/JEECorbaHost.java +++ b/java/sca/modules/host-corba-jee/src/main/java/org/apache/tuscany/sca/host/corba/jee/JEECorbaHost.java @@ -158,4 +158,12 @@ public class JEECorbaHost implements CorbaHost { } } + public void createLocalNameServer(int port) throws CorbaHostException { + // no need to start - server is provided by environment + } + + public void releaseLocalNameServer(int port) throws CorbaHostException { + // no need to release - server is provided by environment + } + } diff --git a/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/CorbaHost.java b/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/CorbaHost.java index f68fb21737..17e9566e17 100644 --- a/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/CorbaHost.java +++ b/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/CorbaHost.java @@ -19,7 +19,6 @@ package org.apache.tuscany.sca.host.corba; -import org.omg.CORBA.ORB; import org.omg.CORBA.Object; /** @@ -29,6 +28,7 @@ public interface CorbaHost { /** * Registers servant in name server. + * * @param uri corbaname URI * @param serviceObject * @throws CorbaHostException @@ -37,18 +37,35 @@ public interface CorbaHost { /** * Removes servant from name server + * * @param orb The ORB instance * @param name binding name * @throws CorbaHostException */ void unregisterServant(String uri) throws CorbaHostException; - + /** * Gets reference to object + * * @param name binding name * @return objects reference * @throws CorbaHostException */ Object lookup(String uri) throws CorbaHostException; + /** + * Provides name server under given port. + * + * @param port + * @throws CorbaHostException + */ + void createLocalNameServer(int port) throws CorbaHostException; + + /** + * Stops name server but only if every client released previously created NS. + * + * @param port + * @throws CorbaHostException + */ + void releaseLocalNameServer(int port) throws CorbaHostException; } diff --git a/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/ExtensibleCorbaHost.java b/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/ExtensibleCorbaHost.java index 73471d658a..1c36fca57d 100644 --- a/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/ExtensibleCorbaHost.java +++ b/java/sca/modules/host-corba/src/main/java/org/apache/tuscany/sca/host/corba/ExtensibleCorbaHost.java @@ -19,7 +19,6 @@ package org.apache.tuscany.sca.host.corba; -import org.omg.CORBA.ORB; import org.omg.CORBA.Object; /** @@ -52,4 +51,12 @@ public class ExtensibleCorbaHost implements CorbaHost { return hosts.getCorbaHosts().get(0); } + public void createLocalNameServer(int port) throws CorbaHostException { + getCorbaHost().createLocalNameServer(port); + } + + public void releaseLocalNameServer(int port) throws CorbaHostException { + getCorbaHost().releaseLocalNameServer(port); + } + } -- cgit v1.2.3