You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2012/03/23 07:18:27 UTC
svn commit: r1304198 [1/3] - in /openejb/trunk/openejb:
itests/failover/src/main/java/org/apache/openejb/server/control/
itests/failover/src/test/java/org/apache/openejb/itest/failover/
server/openejb-client/ server/openejb-client/src/main/java/org/apa...
Author: dblevins
Date: Fri Mar 23 06:18:25 2012
New Revision: 1304198
URL: http://svn.apache.org/viewvc?rev=1304198&view=rev
Log:
OPENEJB-1801 Improved StickyConnectionStrategy for clustering and failover
OPENEJB-1802 Improved RoundRobinConnectionStrategy for clustering and failover
OPENEJB-1803 Improved RandomConnectionStrategy for clustering and failover
OPENEJB-1804 Client Event API for monitoring connection, clustering and failover activity
OPENEJB-1805 All client logging revised and greatly expanded
OPENEJB-1806 New "sticky+random" ConnectionStrategy
OPENEJB-1807 New "sticky+round" ConnectionStrategy
OPENEJB-1808 Client property 'openejb.client.connection.strategy' can be set as System or InitialContext property
OPENEJB-1809 RandomConnectionStrategy fixed reliability issues
OPENEJB-1810 Client Event issued when Servers Added/Removed from cluster
OPENEJB-1811 Client Event issued on connection Failover and Request Retry
OPENEJB-1812 Client Event issued on Configuration change
Many more events than what is listed above. Ideally we'd javadoc them all
Added:
openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/Context.java
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ClientThread.java
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RandomConnectionStrategyTest.java
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RoundRobinConnectionStrategyTest.java
- copied, changed from r1302856, openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/SpeedTest.java
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/StickyConnectionStrategyTest.java
- copied, changed from r1302856, openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/DedicatedRootServerTest.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/AbstractConnectionStrategy.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Context.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EventLogger.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Observers.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/BootstrappingConnection.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ClientVersion.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ClusterMetaDataUpdated.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ConnectionFactoryAdded.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ConnectionFactoryRemoved.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ConnectionFailed.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ConnectionOpened.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ConnectionStrategyAdded.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ConnectionStrategyFailed.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ConnectionStrategyRemoved.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/FailoverSelection.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/Log.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ObserverAdded.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ObserverRemoved.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/Observes.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/RandomFailoverSelection.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/RemoteInitialContextCreated.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/RequestFailed.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/RetryConditionAdded.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/RetryConditionRemoved.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/RetryingRequest.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/RoundRobinFailoverSelection.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ServerAdded.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/ServerRemoved.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/event/StickyFailoverSelection.java
openejb/trunk/openejb/server/openejb-client/src/main/resources/openejb-client-version.properties
openejb/trunk/openejb/server/openejb-client/src/test/java/org/apache/openejb/client/RandomConnectionStrategyIteratorTest.java
openejb/trunk/openejb/server/openejb-client/src/test/java/org/apache/openejb/client/RoundRobinConnectionStrategyIteratorTest.java
openejb/trunk/openejb/server/openejb-client/src/test/java/org/apache/openejb/client/StickyConnectionStrategyIteratorTest.java
openejb/trunk/openejb/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/StaticFailoverTest.java
- copied, changed from r1302856, openejb/trunk/openejb/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/FullPoolFailoverTest.java
Removed:
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/DedicatedRootServerTest.java
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/SpeedTest.java
openejb/trunk/openejb/server/openejb-client/src/test/java/org/apache/openejb/client/StickyConnectionStrategyTest.java
Modified:
openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/StandaloneServer.java
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/FailoverTest.java
openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ReconnectDelayTest.java
openejb/trunk/openejb/server/openejb-client/pom.xml
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterMetaData.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ConnectionManager.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/RandomConnectionStrategy.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/RoundRobinConnectionStrategy.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/SocketConnectionFactory.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/StickyConnectionStrategy.java
openejb/trunk/openejb/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/FullPoolFailoverTest.java
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/Tracker.java
Added: openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/Context.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/Context.java?rev=1304198&view=auto
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/Context.java (added)
+++ openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/Context.java Fri Mar 23 06:18:25 2012
@@ -0,0 +1,42 @@
+/*
+ * 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.openejb.server.control;
+
+import java.util.HashMap;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class Context {
+
+ private final HashMap<Class, Object> components = new HashMap<Class, Object>();
+
+ @SuppressWarnings({"unchecked"})
+ public <T> T get(Class<T> type) {
+ return (T) components.get(type);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public <T> T set(Class<T> type, T component) {
+ return (T) components.put(type, component);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public <T> T remove(Class<T> type) {
+ return (T) components.remove(type);
+ }
+}
Modified: openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/StandaloneServer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/StandaloneServer.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/StandaloneServer.java (original)
+++ openejb/trunk/openejb/itests/failover/src/main/java/org/apache/openejb/server/control/StandaloneServer.java Fri Mar 23 06:18:25 2012
@@ -56,6 +56,7 @@ public class StandaloneServer {
private boolean verbose = false;
private OutputStream out = System.out;
private Options options = new Options(properties);
+ private Context context = new Context();
public StandaloneServer(File home) {
this(home, home);
@@ -78,6 +79,17 @@ public class StandaloneServer {
jvmOpts.add("-javaagent:" + javaagentJar.getAbsolutePath());
}
+ /**
+ * Used as a convenience for tracking objects associated
+ * with this server. Does not affect the running server
+ * and none of these objects are in any way sent or part
+ * of the server itself.
+ * @return
+ */
+ public Context getContext() {
+ return context;
+ }
+
public ServerService getServerService(String string) {
return new ServerService(string);
}
@@ -135,6 +147,10 @@ public class StandaloneServer {
return this;
}
+ public Object get(String name) {
+ return properties.get(this.name + "." + name);
+ }
+
public ServerService threads(int threads) {
setThreads(threads);
return this;
Added: openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ClientThread.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ClientThread.java?rev=1304198&view=auto
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ClientThread.java (added)
+++ openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ClientThread.java Fri Mar 23 06:18:25 2012
@@ -0,0 +1,79 @@
+/*
+ * 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.openejb.itest.failover;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+* @version $Rev$ $Date$
+*/
+public class ClientThread implements Runnable {
+
+ private final AtomicBoolean run = new AtomicBoolean(false);
+ private final AtomicLong delay = new AtomicLong(0);
+ private final Callable callable;
+
+ public ClientThread(Callable callable) {
+ this.callable = callable;
+ }
+
+ @Override
+ public void run() {
+ while (run.get()) {
+ pause();
+
+ try {
+ callable.call();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public ClientThread delay(long delay){
+ setDelay(delay);
+ return this;
+ }
+
+ public void setDelay(long delay) {
+ this.delay.set(delay);
+ }
+
+ private void pause() {
+ final long l = delay.get();
+ try {
+ if (l > 0) Thread.sleep(l);
+ } catch (InterruptedException e) {
+ Thread.interrupted();
+ }
+ }
+
+ public ClientThread start() {
+ run.set(true);
+ final Thread thread = new Thread(this);
+ thread.setDaemon(true);
+ thread.start();
+ return this;
+ }
+
+ public ClientThread stop() {
+ run.set(false);
+ return this;
+ }
+}
Modified: openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/FailoverTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/FailoverTest.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/FailoverTest.java (original)
+++ openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/FailoverTest.java Fri Mar 23 06:18:25 2012
@@ -20,13 +20,14 @@ import org.apache.openejb.itest.failover
import org.apache.openejb.loader.Files;
import org.apache.openejb.loader.Zips;
import org.apache.openejb.server.control.StandaloneServer;
-import org.apache.openejb.util.NetworkUtil;
import org.junit.Assert;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
+import static org.apache.openejb.util.NetworkUtil.getNextAvailablePort;
+
/**
* @version $Rev$ $Date$
*/
@@ -74,13 +75,10 @@ public class FailoverTest {
final StandaloneServer.ServerService multipoint = server.getServerService("multipoint");
multipoint.setBind("localhost");
- multipoint.setPort(NetworkUtil.getNextAvailablePort());
+ multipoint.setPort(getNextAvailablePort());
multipoint.setEnabled(true);
multipoint.set("discoveryName", name);
return server;
}
- public int getAvailablePort() {
- return NetworkUtil.getNextAvailablePort();
- }
}
Added: openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RandomConnectionStrategyTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RandomConnectionStrategyTest.java?rev=1304198&view=auto
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RandomConnectionStrategyTest.java (added)
+++ openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RandomConnectionStrategyTest.java Fri Mar 23 06:18:25 2012
@@ -0,0 +1,330 @@
+/*
+ * 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.openejb.itest.failover;
+
+import org.apache.openejb.client.Client;
+import org.apache.openejb.client.RemoteInitialContextFactory;
+import org.apache.openejb.client.event.ClusterMetaDataUpdated;
+import org.apache.openejb.client.event.Observes;
+import org.apache.openejb.itest.failover.ejb.Calculator;
+import org.apache.openejb.loader.Files;
+import org.apache.openejb.loader.IO;
+import org.apache.openejb.loader.Zips;
+import org.apache.openejb.server.control.StandaloneServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.ejb.EJBException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.io.File;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static org.apache.openejb.util.NetworkUtil.getNextAvailablePort;
+
+public class RandomConnectionStrategyTest {
+
+ static final Logger logger = Logger.getLogger("org.apache.openejb.client");
+
+ static {
+ final ConsoleHandler consoleHandler = new ConsoleHandler();
+ consoleHandler.setLevel(Level.FINER);
+ logger.addHandler(consoleHandler);
+ logger.setLevel(Level.FINER);
+ logger.setUseParentHandlers(false);
+ }
+
+ @Test
+ public void test() throws Exception {
+
+// To run in an IDE, uncomment and update this line
+// System.setProperty("version", "4.0.0-beta-3-SNAPSHOT");
+ System.setProperty("openejb.client.connection.strategy", "roundrobin");
+
+ final File zip = Repository.getArtifact("org.apache.openejb", "openejb-standalone", "zip");
+ final File app = Repository.getArtifact("org.apache.openejb.itests", "failover-ejb", "jar");
+
+ final File dir = Files.tmpdir();
+
+ final StandaloneServer root;
+ {
+ final String name = "root";
+ final File home = new File(dir, name);
+
+ Files.mkdir(home);
+ Zips.unzip(zip, home, true);
+
+ root = new StandaloneServer(home, home);
+ root.killOnExit();
+ root.ignoreOut();
+ root.setProperty("name", name);
+ root.setProperty("openejb.extract.configuration", "false");
+
+ final StandaloneServer.ServerService multipoint = root.getServerService("multipoint");
+ multipoint.setBind("localhost");
+ multipoint.setPort(getNextAvailablePort());
+ multipoint.setDisabled(false);
+ multipoint.set("discoveryName", name);
+
+ logger.info("Starting Root server");
+ root.start();
+ }
+
+ final Services services = new Services();
+ Client.addEventObserver(services);
+
+ final Map<String, StandaloneServer> servers = new HashMap<String, StandaloneServer>();
+ for (String name : new String[]{"red", "green", "blue"}) {
+
+ final File home = new File(dir, name);
+ Files.mkdir(home);
+ Zips.unzip(zip, home, true);
+
+ final StandaloneServer server = new StandaloneServer(home, home);
+ server.killOnExit();
+ server.ignoreOut();
+ server.setProperty("name", name);
+ server.setProperty("openejb.extract.configuration", "false");
+
+ IO.copy(app, Files.path(home, "apps", "itest.jar"));
+ IO.copy(IO.read("<openejb><Deployments dir=\"apps/\"/></openejb>"), Files.path(home, "conf", "openejb.xml"));
+
+ final StandaloneServer.ServerService ejbd = server.getServerService("ejbd");
+ ejbd.setBind("localhost");
+ ejbd.setDisabled(false);
+ ejbd.setPort(getNextAvailablePort());
+ ejbd.setThreads(5);
+
+ final URI uri = URI.create(String.format("ejbd://%s:%s/%s", ejbd.getBind(), ejbd.getPort(), name));
+ ejbd.set("discovery", "ejb:" + uri);
+ services.add(uri);
+ server.getContext().set(URI.class, uri);
+
+ final StandaloneServer.ServerService multipoint = server.getServerService("multipoint");
+ multipoint.setPort(getNextAvailablePort());
+ multipoint.setDisabled(false);
+ multipoint.set("discoveryName", name);
+ multipoint.set("initialServers", "localhost:" + root.getServerService("multipoint").getPort());
+
+ servers.put(name, server);
+
+ logger.info(String.format("Starting %s server", name));
+
+ server.start(1, TimeUnit.MINUTES);
+ }
+
+
+ System.setProperty("openejb.client.requestretry", "true");
+ System.setProperty("openejb.client.connection.strategy", "random");
+
+ logger.info("Beginning Test");
+
+ final Properties environment = new Properties();
+ environment.put(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
+ environment.put(Context.PROVIDER_URL, "ejbd://localhost:" + servers.values().iterator().next().getServerService("ejbd").getPort() + "/provider");
+
+ final InitialContext context = new InitialContext(environment);
+ final Calculator bean = (Calculator) context.lookup("CalculatorBeanRemote");
+
+ for (Map.Entry<String, StandaloneServer> entry : servers.entrySet()) {
+ final String name = entry.getKey();
+ final StandaloneServer server = entry.getValue();
+ final URI serverURI = server.getContext().get(URI.class);
+
+ logger.info("Waiting for updated list");
+ services.assertServices(10, TimeUnit.SECONDS, new CalculatorCallable(bean), 500);
+
+ logger.info("Asserting balance");
+ assertBalance(bean, services.get().size());
+
+ logger.info("Shutting down " + name);
+ server.kill();
+ services.remove(serverURI);
+ }
+
+ logger.info("All Servers Shutdown");
+
+ try {
+ logger.info("Making one last request, expecting complete failover");
+
+ final String name = bean.name();
+ Assert.fail("Server should be destroyed: " + name);
+ } catch (EJBException e) {
+ logger.info(String.format("Pass. Request resulted in %s: %s", e.getCause().getClass().getSimpleName(), e.getMessage()));
+ // good
+ }
+
+
+ for (Map.Entry<String, StandaloneServer> entry : servers.entrySet()) {
+ final String name = entry.getKey();
+ final StandaloneServer server = entry.getValue();
+ final URI serverURI = server.getContext().get(URI.class);
+
+ logger.info(String.format("Starting %s server", name));
+
+ server.start(1, TimeUnit.MINUTES);
+ services.add(serverURI);
+
+ logger.info("Waiting for updated list");
+ services.assertServices(10, TimeUnit.SECONDS, new CalculatorCallable(bean), 500);
+
+ logger.info("Asserting balance");
+ assertBalance(bean, services.get().size());
+ }
+ }
+
+ private void assertBalance(Calculator bean, int size) {
+ final int expectedInvocations = 1000;
+ final double percent = 0.10;
+ final int totalInvocations = size * expectedInvocations;
+
+
+ // Verify the work reached all servers
+ Set<Map.Entry<String, AtomicInteger>> entries = invoke(bean, totalInvocations).entrySet();
+
+ Assert.assertEquals(size, entries.size());
+
+ // And each server got a minimum of %10 percent of the traffic
+ for (Map.Entry<String, AtomicInteger> entry : entries) {
+
+ final int actualInvocations = entry.getValue().get();
+
+ Assert.assertTrue(String.format("%s out of %s is too low", actualInvocations, expectedInvocations), actualInvocations > expectedInvocations * percent );
+ }
+ }
+
+
+ private Map<String, AtomicInteger> invoke(Calculator bean, int max) {
+ final Map<String, AtomicInteger> invocations = new HashMap<String, AtomicInteger>();
+ for (int i = 0; i < max; i++) {
+ final String name = bean.name();
+
+ if (!invocations.containsKey(name)) {
+ invocations.put(name, new AtomicInteger());
+ }
+
+ invocations.get(name).incrementAndGet();
+ }
+
+ for (Map.Entry<String, AtomicInteger> entry : invocations.entrySet()) {
+ logger.info(String.format("Server %s invoked %s times", entry.getKey(), entry.getValue()));
+ }
+
+ return invocations;
+ }
+
+ public static class Services {
+ static final Logger logger = Logger.getLogger(Services.class.getName());
+
+ private final ReentrantLock lock = new ReentrantLock();
+ private final Condition condition = lock.newCondition();
+
+ private final Set<URI> expected = new HashSet<URI>();
+
+ public Services() {
+ }
+
+ public Set<URI> get() {
+ return expected;
+ }
+
+ public boolean add(URI uri) {
+ return expected.add(uri);
+ }
+
+ public boolean remove(URI o) {
+ return expected.remove(o);
+ }
+
+ public void observe(@Observes ClusterMetaDataUpdated updated) {
+ final URI[] locations = updated.getClusterMetaData().getLocations();
+ final Set<URI> found = new HashSet<URI>(Arrays.asList(locations));
+
+ if (expected.equals(found)) {
+ lock.lock();
+ try {
+ condition.signal();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ public Set<URI> diff(Set<URI> a, Set<URI> b) {
+ final Set<URI> diffs = new HashSet<URI>();
+ for (URI uri : b) {
+ if (!a.contains(uri)) diffs.add(uri);
+ }
+
+ return diffs;
+ }
+
+ public void assertServices(long timeout, TimeUnit unit, Callable callable) {
+ assertServices(timeout, unit, callable, 10);
+ }
+
+ public void assertServices(long timeout, TimeUnit unit, Callable callable, int delay) {
+ final ClientThread client = new ClientThread(callable);
+ client.delay(delay);
+ client.start();
+ try {
+ Assert.assertTrue(String.format("services failed to come online: waited %s %s", timeout, unit), await(timeout, unit));
+ } catch (InterruptedException e) {
+ Thread.interrupted();
+ Assert.fail("Interrupted");
+ } finally {
+ client.stop();
+ }
+ }
+
+ public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
+ lock.lock();
+ try {
+ return condition.await(timeout, unit);
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ private static class CalculatorCallable implements Callable {
+ private final Calculator bean;
+
+ public CalculatorCallable(Calculator bean) {
+ this.bean = bean;
+ }
+
+ @Override
+ public Object call() throws Exception {
+ return bean.name();
+ }
+ }
+}
Modified: openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ReconnectDelayTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ReconnectDelayTest.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ReconnectDelayTest.java (original)
+++ openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/ReconnectDelayTest.java Fri Mar 23 06:18:25 2012
@@ -52,7 +52,7 @@ public class ReconnectDelayTest {
public void test() throws Exception {
// To run in an IDE, uncomment and update this line
- //System.setProperty("version", "4.0.0-beta-3-SNAPSHOT");
+ System.setProperty("version", "4.0.0-beta-3-SNAPSHOT");
Duration reconnectDelay = new Duration("1 second");
Copied: openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RoundRobinConnectionStrategyTest.java (from r1302856, openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/SpeedTest.java)
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RoundRobinConnectionStrategyTest.java?p2=openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RoundRobinConnectionStrategyTest.java&p1=openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/SpeedTest.java&r1=1302856&r2=1304198&rev=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/SpeedTest.java (original)
+++ openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/RoundRobinConnectionStrategyTest.java Fri Mar 23 06:18:25 2012
@@ -16,7 +16,10 @@
*/
package org.apache.openejb.itest.failover;
+import org.apache.openejb.client.Client;
import org.apache.openejb.client.RemoteInitialContextFactory;
+import org.apache.openejb.client.event.ClusterMetaDataUpdated;
+import org.apache.openejb.client.event.Observes;
import org.apache.openejb.itest.failover.ejb.Calculator;
import org.apache.openejb.loader.Files;
import org.apache.openejb.loader.IO;
@@ -29,32 +32,77 @@ import javax.ejb.EJBException;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
-
-public class SpeedTest extends FailoverTest {
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static org.apache.openejb.util.NetworkUtil.getNextAvailablePort;
+
+public class RoundRobinConnectionStrategyTest {
+
+ static final Logger logger = Logger.getLogger("org.apache.openejb.client");
+
+ static {
+ final ConsoleHandler consoleHandler = new ConsoleHandler();
+ consoleHandler.setLevel(Level.FINER);
+ logger.addHandler(consoleHandler);
+ logger.setLevel(Level.FINER);
+ logger.setUseParentHandlers(false);
+ }
@Test
public void test() throws Exception {
- // To run in an IDE, uncomment and update this line
- //System.setProperty("version", "4.0.0-beta-3-SNAPSHOT");
+// To run in an IDE, uncomment and update this line
+// System.setProperty("version", "4.0.0-beta-3-SNAPSHOT");
+ System.setProperty("openejb.client.connection.strategy", "roundrobin");
final File zip = Repository.getArtifact("org.apache.openejb", "openejb-standalone", "zip");
final File app = Repository.getArtifact("org.apache.openejb.itests", "failover-ejb", "jar");
final File dir = Files.tmpdir();
- final StandaloneServer root = createMultipointServer(zip, dir, "root");
- root.setOut(System.out);
- root.start(1, TimeUnit.MINUTES);
+ final StandaloneServer root;
+ {
+ final String name = "root";
+ final File home = new File(dir, name);
+
+ Files.mkdir(home);
+ Zips.unzip(zip, home, true);
+
+ root = new StandaloneServer(home, home);
+ root.killOnExit();
+ root.ignoreOut();
+ root.setProperty("name", name);
+ root.setProperty("openejb.extract.configuration", "false");
+
+ final StandaloneServer.ServerService multipoint = root.getServerService("multipoint");
+ multipoint.setBind("localhost");
+ multipoint.setPort(getNextAvailablePort());
+ multipoint.setDisabled(false);
+ multipoint.set("discoveryName", name);
+
+ logger.info("Starting Root server");
+ root.start();
+ }
- final List<StandaloneServer> servers = new ArrayList<StandaloneServer>();
+ final Services services = new Services();
+ Client.addEventObserver(services);
- for (String name : new String[]{"red", "green", "blue", "yellow", "orange"}) {
+ final Map<String, StandaloneServer> servers = new HashMap<String, StandaloneServer>();
+ for (String name : new String[]{"red", "green", "blue"}) {
final File home = new File(dir, name);
Files.mkdir(home);
@@ -70,64 +118,208 @@ public class SpeedTest extends FailoverT
IO.copy(IO.read("<openejb><Deployments dir=\"apps/\"/></openejb>"), Files.path(home, "conf", "openejb.xml"));
final StandaloneServer.ServerService ejbd = server.getServerService("ejbd");
+ ejbd.setBind("localhost");
ejbd.setDisabled(false);
- ejbd.setPort(getAvailablePort());
+ ejbd.setPort(getNextAvailablePort());
ejbd.setThreads(5);
+ final URI uri = URI.create(String.format("ejbd://%s:%s/%s", ejbd.getBind(), ejbd.getPort(), name));
+ ejbd.set("discovery", "ejb:" + uri);
+ services.add(uri);
+ server.getContext().set(URI.class, uri);
+
final StandaloneServer.ServerService multipoint = server.getServerService("multipoint");
- multipoint.setPort(getAvailablePort());
+ multipoint.setPort(getNextAvailablePort());
multipoint.setDisabled(false);
multipoint.set("discoveryName", name);
- multipoint.set("initialServers", "localhost:"+root.getServerService("multipoint").getPort());
+ multipoint.set("initialServers", "localhost:" + root.getServerService("multipoint").getPort());
- server.start(1, TimeUnit.MINUTES);
+ servers.put(name, server);
+
+ logger.info(String.format("Starting %s server", name));
- servers.add(server);
+ server.start(1, TimeUnit.MINUTES);
}
- Collections.reverse(servers);
System.setProperty("openejb.client.requestretry", "true");
+ System.setProperty("openejb.client.connection.strategy", "roundrobin");
+
+ logger.info("Beginning Test");
final Properties environment = new Properties();
environment.put(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
- environment.put(Context.PROVIDER_URL, "failover:ejbd://localhost:" + servers.get(0).getServerService("ejbd").getPort());
+ environment.put(Context.PROVIDER_URL, "ejbd://localhost:" + servers.values().iterator().next().getServerService("ejbd").getPort() + "/provider");
final InitialContext context = new InitialContext(environment);
final Calculator bean = (Calculator) context.lookup("CalculatorBeanRemote");
- // Hotspotting doesn't kick in with just a few invocations
- // Later we'll be doing thousands of invocations and that will
- // bring the invoke time down significantly
-
- // With this test we're looking for issues with failed servers
- // causing delays even though they should have been removed from
- // the clients invocation list
-
- final long slowest = invoke(bean, 5);
- System.out.printf("Base invocation speed: %s microseconds", slowest);
- System.out.println();
-
- for (StandaloneServer server : servers) {
- final long speed = invoke(bean, 10000);
- Assert.assertTrue(String.format("Average invocation time %s microseconds higher than pre-hotspot time of %s microseconds", speed, slowest), speed < slowest);
+ for (Map.Entry<String, StandaloneServer> entry : servers.entrySet()) {
+ final String name = entry.getKey();
+ final StandaloneServer server = entry.getValue();
+ final URI serverURI = server.getContext().get(URI.class);
+
+ logger.info("Waiting for updated list");
+ services.assertServices(10, TimeUnit.SECONDS, new CalculatorCallable(bean), 500);
+
+ logger.info("Asserting balance");
+ assertBalance(bean, services.get().size());
+
+ logger.info("Shutting down " + name);
server.kill();
+ services.remove(serverURI);
}
- System.out.println("All servers destroyed");
+ logger.info("All Servers Shutdown");
try {
- System.out.println(String.format("Average invocation time %s microseconds", invoke(bean, 10000)));
- Assert.fail("Server should be destroyed");
+ logger.info("Making one last request, expecting complete failover");
+
+ final String name = bean.name();
+ Assert.fail("Server should be destroyed: " + name);
} catch (EJBException e) {
+ logger.info(String.format("Pass. Request resulted in %s: %s", e.getCause().getClass().getSimpleName(), e.getMessage()));
// good
}
- final StandaloneServer server = servers.get(0);
- server.start(1, TimeUnit.MINUTES);
- final long speed = invoke(bean, 10000);
- Assert.assertTrue(String.format("Average invocation time %s microseconds higher than pre-hotspot time of %s microseconds", speed, slowest), speed < slowest);
+ for (Map.Entry<String, StandaloneServer> entry : servers.entrySet()) {
+ final String name = entry.getKey();
+ final StandaloneServer server = entry.getValue();
+ final URI serverURI = server.getContext().get(URI.class);
+
+ logger.info(String.format("Starting %s server", name));
+
+ server.start(1, TimeUnit.MINUTES);
+ services.add(serverURI);
+
+ logger.info("Waiting for updated list");
+ services.assertServices(10, TimeUnit.SECONDS, new CalculatorCallable(bean), 500);
+
+ logger.info("Asserting balance");
+ assertBalance(bean, services.get().size());
+ }
+ }
+
+ private void assertBalance(Calculator bean, int size) {
+ final int expectedInvocations = 100;
+ final int tolerance = 2;
+ final int totalInvocations = size * expectedInvocations + (size * tolerance);
+
+
+ // Verify the work was split up more or less evenly (within a tolerance of 2)
+ for (Map.Entry<String, AtomicInteger> entry : invoke(bean, totalInvocations).entrySet()) {
+
+ final int actualInvocations = entry.getValue().get();
+
+ Assert.assertTrue(String.format("Expected %s invocations, received %s", expectedInvocations, actualInvocations), actualInvocations >= expectedInvocations && actualInvocations <= (expectedInvocations + tolerance + size) );
+ }
+ }
+
+ private Map<String, AtomicInteger> invoke(Calculator bean, int max) {
+ final Map<String, AtomicInteger> invocations = new HashMap<String, AtomicInteger>();
+ for (int i = 0; i < max; i++) {
+ final String name = bean.name();
+
+ if (!invocations.containsKey(name)) {
+ invocations.put(name, new AtomicInteger());
+ }
+
+ invocations.get(name).incrementAndGet();
+ }
+
+ for (Map.Entry<String, AtomicInteger> entry : invocations.entrySet()) {
+ logger.info(String.format("Server %s invoked %s times", entry.getKey(), entry.getValue()));
+ }
+
+ return invocations;
+ }
+
+ public static class Services {
+ static final Logger logger = Logger.getLogger(Services.class.getName());
+
+ private final ReentrantLock lock = new ReentrantLock();
+ private final Condition condition = lock.newCondition();
+
+ private final Set<URI> expected = new HashSet<URI>();
+
+ public Services() {
+ }
+
+ public Set<URI> get() {
+ return expected;
+ }
+
+ public boolean add(URI uri) {
+ return expected.add(uri);
+ }
+
+ public boolean remove(URI o) {
+ return expected.remove(o);
+ }
+
+ public void observe(@Observes ClusterMetaDataUpdated updated) {
+ final URI[] locations = updated.getClusterMetaData().getLocations();
+ final Set<URI> found = new HashSet<URI>(Arrays.asList(locations));
+
+ if (expected.equals(found)) {
+ lock.lock();
+ try {
+ condition.signal();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ public Set<URI> diff(Set<URI> a, Set<URI> b) {
+ final Set<URI> diffs = new HashSet<URI>();
+ for (URI uri : b) {
+ if (!a.contains(uri)) diffs.add(uri);
+ }
+
+ return diffs;
+ }
+
+ public void assertServices(long timeout, TimeUnit unit, Callable callable) {
+ assertServices(timeout, unit, callable, 10);
+ }
+
+ public void assertServices(long timeout, TimeUnit unit, Callable callable, int delay) {
+ final ClientThread client = new ClientThread(callable);
+ client.delay(delay);
+ client.start();
+ try {
+ Assert.assertTrue(String.format("services failed to come online: waited %s %s", timeout, unit), await(timeout, unit));
+ } catch (InterruptedException e) {
+ Thread.interrupted();
+ Assert.fail("Interrupted");
+ } finally {
+ client.stop();
+ }
+ }
+
+ public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
+ lock.lock();
+ try {
+ return condition.await(timeout, unit);
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ private static class CalculatorCallable implements Callable {
+ private final Calculator bean;
+
+ public CalculatorCallable(Calculator bean) {
+ this.bean = bean;
+ }
+
+ @Override
+ public Object call() throws Exception {
+ return bean.name();
+ }
}
}
Copied: openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/StickyConnectionStrategyTest.java (from r1302856, openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/DedicatedRootServerTest.java)
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/StickyConnectionStrategyTest.java?p2=openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/StickyConnectionStrategyTest.java&p1=openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/DedicatedRootServerTest.java&r1=1302856&r2=1304198&rev=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/DedicatedRootServerTest.java (original)
+++ openejb/trunk/openejb/itests/failover/src/test/java/org/apache/openejb/itest/failover/StickyConnectionStrategyTest.java Fri Mar 23 06:18:25 2012
@@ -36,6 +36,9 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -51,13 +54,22 @@ import static org.junit.Assert.assertFal
* service EJB requests.
*
*/
-public class DedicatedRootServerTest {
+public class StickyConnectionStrategyTest {
+
+ static final Logger logger = Logger.getLogger("org.apache.openejb.client");
+ static {
+ final ConsoleHandler consoleHandler = new ConsoleHandler();
+ consoleHandler.setLevel(Level.FINER);
+ logger.addHandler(consoleHandler);
+ logger.setLevel(Level.FINER);
+ logger.setUseParentHandlers(false);
+ }
@Test
public void test() throws Exception {
// To run in an IDE, uncomment and update this line
- //System.setProperty("version", "4.0.0-beta-3-SNAPSHOT");
+// System.setProperty("version", "4.0.0-beta-3-SNAPSHOT");
final File zip = Repository.getArtifact("org.apache.openejb", "openejb-standalone", "zip");
final File app = Repository.getArtifact("org.apache.openejb.itests", "failover-ejb", "jar");
@@ -86,6 +98,7 @@ public class DedicatedRootServerTest {
multipoint.set("discoveryName", name);
root = root1;
+ logger.info("Starting Root server");
root.start();
}
@@ -106,9 +119,11 @@ public class DedicatedRootServerTest {
IO.copy(IO.read("<openejb><Deployments dir=\"apps/\"/></openejb>"), Files.path(home, "conf", "openejb.xml"));
final StandaloneServer.ServerService ejbd = server.getServerService("ejbd");
+ ejbd.setBind("localhost");
ejbd.setDisabled(false);
ejbd.setPort(getAvailablePort());
ejbd.setThreads(5);
+ ejbd.set("discovery", "ejb:ejbd://{bind}:{port}/" + name);
final StandaloneServer.ServerService multipoint = server.getServerService("multipoint");
multipoint.setPort(getAvailablePort());
@@ -117,6 +132,9 @@ public class DedicatedRootServerTest {
multipoint.set("initialServers", "localhost:"+root.getServerService("multipoint").getPort());
servers.put(name, server);
+
+ logger.info(String.format("Starting %s server", name));
+
server.start(1, TimeUnit.MINUTES);
invoke(name, server);
@@ -124,9 +142,11 @@ public class DedicatedRootServerTest {
System.setProperty("openejb.client.requestretry", "true");
+ logger.info("Beginning Test");
+
final Properties environment = new Properties();
environment.put(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
- environment.put(Context.PROVIDER_URL, "ejbd://localhost:" + servers.values().iterator().next().getServerService("ejbd").getPort());
+ environment.put(Context.PROVIDER_URL, "ejbd://localhost:" + servers.values().iterator().next().getServerService("ejbd").getPort() + "/provider");
final InitialContext context = new InitialContext(environment);
final Calculator bean = (Calculator) context.lookup("CalculatorBeanRemote");
@@ -135,9 +155,13 @@ public class DedicatedRootServerTest {
String previous = null;
for (StandaloneServer ignored : servers.values()) {
+ logger.info("Looping");
+
// What server are we talking to now?
final String name = bean.name();
+ logger.info("Sticky request to " + name);
+
// The root should not be serving apps
assertFalse("root".equals(name));
@@ -145,26 +169,43 @@ public class DedicatedRootServerTest {
if (previous != null) assertFalse(name.equals(previous));
previous = name;
+ final int i = 1000;
+
+ logger.info(String.format("Performing %s invocations, expecting %s to be used for each invocation.", i, name));
+
// Should be the same server for the next N calls
- invoke(bean, 1000, name);
+ invoke(bean, i, name);
+
+ logger.info("Shutting down " + name);
// Now let's kill that server
servers.get(name).kill();
}
- System.out.println("All servers destroyed");
+ logger.info("All Servers Shutdown");
try {
+ logger.info("Making one last request, expecting complete failover");
+
final String name = bean.name();
Assert.fail("Server should be destroyed: " + name);
} catch (EJBException e) {
+ logger.info(String.format("Pass. Request resulted in %s: %s", e.getCause().getClass().getSimpleName(), e.getMessage()));
// good
}
+
// Let's start a server again and invocations should now succeed
final Iterator<StandaloneServer> iterator = servers.values().iterator();
iterator.next();
- iterator.next().start(1, TimeUnit.MINUTES);
+
+ final StandaloneServer server = iterator.next();
+
+ logger.info(String.format("Starting %s server", server.getProperties().get("name")));
+
+ server.start(1, TimeUnit.MINUTES);
+
+ logger.info("Performing one more invocation");
assertEquals(5, bean.sum(2, 3));
}
@@ -172,7 +213,7 @@ public class DedicatedRootServerTest {
private void invoke(String name, StandaloneServer server) throws NamingException {
final Properties environment = new Properties();
environment.put(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
- environment.put(Context.PROVIDER_URL, "ejbd://localhost:" + server.getServerService("ejbd").getPort());
+ environment.put(Context.PROVIDER_URL, "ejbd://localhost:" + server.getServerService("ejbd").getPort() + "/" + name);
final InitialContext context = new InitialContext(environment);
final Calculator bean = (Calculator) context.lookup("CalculatorBeanRemote");
Modified: openejb/trunk/openejb/server/openejb-client/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/pom.xml?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/pom.xml (original)
+++ openejb/trunk/openejb/server/openejb-client/pom.xml Fri Mar 23 06:18:25 2012
@@ -64,6 +64,12 @@
</openejb.osgi.export.pkg>
</properties>
<build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -92,6 +98,30 @@
</excludes>
</configuration>
</plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <tstamp>
+ <format property="TSTAMP" pattern="hh:mm"/>
+ </tstamp>
+ <replace file="target/classes/openejb-client-version.properties"
+ token="@DATE-REPLACED-BY-MAVEN@" value="${DSTAMP}"/>
+ <replace file="target/classes/openejb-client-version.properties"
+ token="@TIME-REPLACED-BY-MAVEN@" value="${TSTAMP}"/>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
<dependencies>
Added: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/AbstractConnectionStrategy.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/AbstractConnectionStrategy.java?rev=1304198&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/AbstractConnectionStrategy.java (added)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/AbstractConnectionStrategy.java Fri Mar 23 06:18:25 2012
@@ -0,0 +1,105 @@
+/*
+ * 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.openejb.client;
+
+import org.apache.openejb.client.event.BootstrappingConnection;
+import org.apache.openejb.client.event.FailoverSelection;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractConnectionStrategy implements ConnectionStrategy {
+ public Connection connect(ClusterMetaData cluster, ServerMetaData server) throws IOException {
+ final Set<URI> failed = Client.getFailed();
+ final Set<URI> remaining = new HashSet<URI>();
+
+ boolean failover = false;
+
+ final Iterable<URI> iterable = getIterable(cluster);
+ for (URI uri : iterable) {
+ if (failed.contains(uri)) continue;
+
+ if (failover) Client.fireEvent(createFailureEvent(remaining, failed, uri));
+
+ try {
+ return connect(cluster, uri);
+ } catch (IOException e) {
+
+ if (!failover) {
+ Collections.addAll(remaining, cluster.getLocations());
+ remaining.removeAll(failed);
+ }
+
+ failed.add(uri);
+ remaining.remove(uri);
+ failover = true;
+ }
+ }
+
+ final URI uri = server.getLocation();
+
+ if (uri == null) throw new RemoteFailoverException("Attempted to connect to " + failed.size() + " servers.");
+
+ Client.fireEvent(new BootstrappingConnection(uri));
+
+ return connect(cluster, uri);
+ }
+
+ private Iterable<URI> getIterable(ClusterMetaData cluster) {
+ final Context context = cluster.getContext();
+ final StrategyData data = context.getComponent(StrategyData.class);
+
+ if (data != null) return data.getIterable();
+
+ context.setComponent(StrategyData.class, new StrategyData(createIterable(cluster)));
+
+ return getIterable(cluster);
+ }
+
+ protected abstract FailoverSelection createFailureEvent(Set<URI> remaining, Set<URI> failed, URI uri);
+
+ protected abstract Iterable<URI> createIterable(ClusterMetaData cluster);
+
+ protected Connection connect(ClusterMetaData cluster, URI uri) throws IOException {
+ Connection connection = ConnectionManager.getConnection(uri);
+
+ // Grabbing the URI from the associated connection allows the ConnectionFactory to
+ // employ discovery to find and connect to a server. We then attempt to connect
+ // to the discovered server rather than repeat the discovery process again.
+ cluster.setLastLocation(connection.getURI());
+ return connection;
+ }
+
+ private static class StrategyData {
+ private final Iterable<URI> iterable;
+
+ private StrategyData(Iterable<URI> iterable) {
+ this.iterable = iterable;
+ }
+
+ public Iterable<URI> getIterable() {
+ return iterable;
+ }
+ }
+}
Modified: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java (original)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java Fri Mar 23 06:18:25 2012
@@ -16,6 +16,16 @@
*/
package org.apache.openejb.client;
+import org.apache.openejb.client.event.ClientVersion;
+import org.apache.openejb.client.event.ClusterMetaDataUpdated;
+import org.apache.openejb.client.event.ObserverAdded;
+import org.apache.openejb.client.event.RequestFailed;
+import org.apache.openejb.client.event.RetryConditionAdded;
+import org.apache.openejb.client.event.RetryConditionRemoved;
+import org.apache.openejb.client.event.RetryingRequest;
+import org.apache.openejb.client.event.ServerAdded;
+import org.apache.openejb.client.event.ServerRemoved;
+
import static org.apache.openejb.client.Exceptions.newIOException;
import java.io.EOFException;
@@ -26,7 +36,9 @@ import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.rmi.RemoteException;
+import java.util.Arrays;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
@@ -38,9 +50,9 @@ import java.net.URI;
public class Client {
private static final Logger logger = Logger.getLogger("OpenEJB.client");
- private static final boolean FINEST = logger.isLoggable(Level.FINEST);
- private static final boolean FINER = logger.isLoggable(Level.FINER);
- private static final boolean FINE = logger.isLoggable(Level.FINE);
+ private boolean FINEST = logger.isLoggable(Level.FINEST);
+ private boolean FINER = logger.isLoggable(Level.FINER);
+ private boolean FINE = logger.isLoggable(Level.FINE);
public static final ThreadLocal<Set<URI>> failed = new ThreadLocal<Set<URI>>();
@@ -50,21 +62,53 @@ public class Client {
private static Client client = new Client();
private boolean retry = false;
+ private final Observers observers = new Observers();
+
public Client() {
String retryValue = System.getProperty("openejb.client.requestretry", getRetry() + "");
retry = Boolean.valueOf(retryValue);
+
+ observers.addObserver(new EventLogger());
+ observers.fireEvent(new ClientVersion());
+ }
+
+ public static void addEventObserver(Object observer) {
+ if (observer == null) throw new IllegalArgumentException("observer cannot be null");
+
+ if (client.observers.addObserver(observer)) {
+ fireEvent(new ObserverAdded(observer));
+ }
+ }
+
+ public static void removeEventObserver(Object observer) {
+ if (observer == null) throw new IllegalArgumentException("observer cannot be null");
+
+ if (client.observers.removeObserver(observer)) {
+ fireEvent(new ObserverAdded(observer));
+ }
+ }
+
+ public static void fireEvent(Object event) {
+ client.observers.fireEvent(event);
}
public static boolean addRetryCondition(Class<? extends Throwable> throwable) {
- return client.retryConditions.add(throwable);
+ if (throwable == null) throw new IllegalArgumentException("throwable cannot be null");
+ final boolean add = client.retryConditions.add(throwable);
+ if (add) fireEvent(new RetryConditionAdded(throwable));
+ return add;
}
public static boolean removeRetryCondition(Class<? extends Throwable> throwable) {
- return client.retryConditions.remove(throwable);
+ if (throwable == null) throw new IllegalArgumentException("throwable cannot be null");
+ final boolean remove = client.retryConditions.remove(throwable);
+ if (remove) fireEvent(new RetryConditionRemoved(throwable));
+ return remove;
}
// This lame hook point if only of testing
public static void setClient(Client client) {
+ if (client == null) throw new IllegalArgumentException("client cannot be null");
Client.client = client;
}
@@ -290,13 +334,19 @@ public class Client {
final URI uri = conn.getURI();
final Set<URI> failed = getFailed();
+ Client.fireEvent(new RequestFailed(uri, req));
+
if (FINER) {
logger.log(Level.FINER, "Add Failed " + uri.toString());
}
failed.add(uri);
conn.discard();
+
if (e instanceof RetryException || getRetry()) {
try {
+
+ Client.fireEvent(new RetryingRequest(req, server));
+
processRequest(req, res, server);
} catch (RemoteFailoverException re) {
throw re;
@@ -349,36 +399,99 @@ public class Client {
return set;
}
- private static final Map<ServerMetaData, ClusterMetaData> clusters = new ConcurrentHashMap<ServerMetaData, ClusterMetaData>();
-
private static void setClusterMetaData(ServerMetaData server, ClusterMetaData cluster) {
+ final Context context = getContext(server);
+ context.setClusterMetaData(cluster);
+ }
+
+ private static ClusterMetaData getClusterMetaData(ServerMetaData server) {
+ return getContext(server).getClusterMetaData();
+ }
+
+ //openejb.client.connection.strategy
+
+ private boolean getRetry() {
+ return retry = Boolean.valueOf(System.getProperty("openejb.client.requestretry", retry + ""));
+ }
+
+ private static final Map<ServerMetaData, Context> contexts = new ConcurrentHashMap<ServerMetaData, Context>();
- if (FINE) {
- logger.log(Level.FINE, "Update ClusterMetaData(version=" + cluster.getVersion() + ", uris=" + cluster.getLocations().length);
+ public static Context getContext(ServerMetaData serverMetaData) {
+ Context context = contexts.get(serverMetaData);
+ if (context == null) {
+ context = new Context(serverMetaData);
+ contexts.put(serverMetaData, context);
}
+ return context;
+ }
+
+ public static class Context {
+ private final Properties properties = new Properties();
+ private final ServerMetaData serverMetaData;
+ private ClusterMetaData clusterMetaData;
+ private Options options;
+
+ private Context(ServerMetaData serverMetaData) {
+ this.serverMetaData = serverMetaData;
+ this.clusterMetaData = new ClusterMetaData(0, serverMetaData.getLocation());
+
+ options = new Options(properties, new Options(System.getProperties()));
+ }
+
+ public ServerMetaData getServerMetaData() {
+ return serverMetaData;
+ }
+
+ public ClusterMetaData getClusterMetaData() {
+ return clusterMetaData;
+ }
+
+ public void setClusterMetaData(ClusterMetaData updated) {
+ if (updated == null) throw new IllegalArgumentException("clusterMetaData cannot be null");
+
+ ClusterMetaData previous = this.clusterMetaData;
+ this.clusterMetaData = updated;
+
+ if (updated.getConnectionStrategy() == null) {
+ updated.setConnectionStrategy(previous.getConnectionStrategy());
+ }
+ updated.setLastLocation(previous.getLastLocation());
+ final ClusterMetaDataUpdated clusterMetaDataUpdated = new ClusterMetaDataUpdated(serverMetaData, updated, clusterMetaData);
+
+ fireEvent(clusterMetaDataUpdated);
+
+ final Set<URI> found = locations(updated);
+ final Set<URI> existing = locations(previous);
- if (FINER) {
- int i = 0;
- for (URI uri : cluster.getLocations()) {
- final String format = String.format("ClusterMetaData(version=%s) - URI #%s %s", cluster.getVersion(), ++i, uri.toASCIIString());
- logger.log(Level.FINER, format);
+ for (URI uri : diff(existing, found)) {
+ fireEvent(new ServerAdded(clusterMetaDataUpdated, uri));
}
+
+ for (URI uri : diff(found, existing)) {
+ fireEvent(new ServerRemoved(clusterMetaDataUpdated, uri));
+ }
+
}
- clusters.put(server, cluster);
- }
+ private HashSet<URI> locations(ClusterMetaData updated) {
+ return new HashSet<URI>(Arrays.asList(updated.getLocations()));
+ }
- private static ClusterMetaData getClusterMetaData(ServerMetaData server) {
- ClusterMetaData cluster = clusters.get(server);
- if (cluster == null) {
- cluster = new ClusterMetaData(0, server.getLocation());
- clusters.put(server, cluster);
+ public Properties getProperties() {
+ return properties;
}
- return cluster;
- }
+ public Options getOptions() {
+ return options;
+ }
- private boolean getRetry() {
- return retry = Boolean.valueOf(System.getProperty("openejb.client.requestretry", retry + ""));
+ public Set<URI> diff(Set<URI> a, Set<URI> b) {
+ final Set<URI> diffs = new HashSet<URI>();
+ for (URI uri : b) {
+ if (!a.contains(uri)) diffs.add(uri);
+ }
+
+ return diffs;
+ }
}
}
Modified: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterMetaData.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterMetaData.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterMetaData.java (original)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterMetaData.java Fri Mar 23 06:18:25 2012
@@ -30,7 +30,8 @@ public class ClusterMetaData implements
private URI[] locations;
private long version;
private String connectionStrategy;
- private URI lastLocation;
+ private volatile URI lastLocation;
+ private transient final Context context = new Context();
public ClusterMetaData() {
}
@@ -40,6 +41,10 @@ public class ClusterMetaData implements
this.version = version;
}
+ public Context getContext() {
+ return context;
+ }
+
public URI getLastLocation() {
return lastLocation;
}
Modified: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ConnectionManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ConnectionManager.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ConnectionManager.java (original)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ConnectionManager.java Fri Mar 23 06:18:25 2012
@@ -16,6 +16,13 @@
*/
package org.apache.openejb.client;
+import org.apache.openejb.client.event.ConnectionFactoryAdded;
+import org.apache.openejb.client.event.ConnectionFactoryRemoved;
+import org.apache.openejb.client.event.ConnectionFailed;
+import org.apache.openejb.client.event.ConnectionStrategyAdded;
+import org.apache.openejb.client.event.ConnectionStrategyFailed;
+import org.apache.openejb.client.event.Log;
+
import java.io.IOException;
import java.net.URI;
import java.util.Properties;
@@ -31,26 +38,31 @@ public class ConnectionManager {
static {
SocketConnectionFactory ejbdFactory = new SocketConnectionFactory();
- factories.register("default", ejbdFactory);
- factories.register("ejbd", ejbdFactory);
- factories.register("ejbds", ejbdFactory);
+ registerFactory("default", ejbdFactory);
+ registerFactory("ejbd", ejbdFactory);
+ registerFactory("ejbds", ejbdFactory);
HttpConnectionFactory httpFactory = new HttpConnectionFactory();
- factories.register("http", httpFactory);
- factories.register("https", httpFactory);
+ registerFactory("http", httpFactory);
+ registerFactory("https", httpFactory);
- factories.register("multicast", new MulticastConnectionFactory());
- factories.register("failover", new FailoverConnectionFactory());
+ registerFactory("multicast", new MulticastConnectionFactory());
+ registerFactory("failover", new FailoverConnectionFactory());
- strategies.register("sticky", new StickyConnectionStrategy());
- strategies.register("random", new RandomConnectionStrategy());
- strategies.register("roundrobin", new RoundRobinConnectionStrategy());
- strategies.register("round-robin", strategies.get("roundrobin"));
- strategies.register("default", strategies.get("sticky"));
+ registerStrategy("sticky", new StickyConnectionStrategy());
+ registerStrategy("sticky+random", new StickyConnectionStrategy(new RandomConnectionStrategy()));
+ registerStrategy("sticky+round", new StickyConnectionStrategy(new RoundRobinConnectionStrategy()));
+ registerStrategy("random", new RandomConnectionStrategy());
+ registerStrategy("roundrobin", new RoundRobinConnectionStrategy());
+ registerStrategy("round-robin", strategies.get("roundrobin"));
+ registerStrategy("default", strategies.get("sticky"));
}
public static Connection getConnection(ClusterMetaData cluster, ServerMetaData server, Request req) throws IOException {
+ if (cluster == null) throw new IllegalArgumentException("cluster cannot be null");
+ if (server == null) throw new IllegalArgumentException("server cannot be null");
+
String name = cluster.getConnectionStrategy();
if (req instanceof EJBRequest) {
@@ -58,41 +70,73 @@ public class ConnectionManager {
final Properties p = ejbRequest.getEjbMetaData().getProperties();
name = p.getProperty("openejb.client.connection.strategy", name);
}
+
if (name == null) name = "default";
ConnectionStrategy strategy = strategies.get(name);
- if (strategy == null) throw new IOException("Unsupported ConnectionStrategy \"" + name + "\"");
+ try {
+ if (strategy == null) throw new UnsupportedConnectionStrategyException(name);
- logger.fine("connect: strategy=" + name + ", uri=" + server.getLocation() + ", strategy-impl=" + strategy.getClass().getName());
- return strategy.connect(cluster, server);
+ // On finest because this happens every invocation
+ logger.finest("connect: strategy=" + name + ", uri=" + server.getLocation() + ", strategy-impl=" + strategy.getClass().getName());
+
+ return strategy.connect(cluster, server);
+ } catch (IOException e) {
+ Client.fireEvent(new ConnectionStrategyFailed(strategy, cluster, server, e));
+ throw e;
+ }
}
public static Connection getConnection(URI uri) throws IOException {
+ if (uri == null) throw new IllegalArgumentException("uri cannot be null");
String scheme = uri.getScheme();
ConnectionFactory factory = factories.get(scheme);
- if (factory == null) throw new IOException("Unsupported ConnectionFactory URI scheme \"" + scheme + "\"");
-
- logger.fine("connect: scheme=" + scheme + ", uri=" + uri + ", factory-impl=" + factory.getClass().getName());
- return factory.getConnection(uri);
+ try {
+ if (factory == null) {
+ throw new UnsupportedConnectionFactoryException(scheme);
+ }
+
+ // On finest because this happens every invocation
+ logger.finest("connect: scheme=" + scheme + ", uri=" + uri + ", factory-impl=" + factory.getClass().getName());
+
+ return factory.getConnection(uri);
+ } catch (IOException e) {
+ Client.fireEvent(new ConnectionFailed(uri, e));
+ throw e;
+ }
}
public static void registerFactory(String scheme, ConnectionFactory factory) {
factories.register(scheme, factory);
+ Client.fireEvent(new ConnectionFactoryAdded(scheme, factory));
}
public static ConnectionFactory unregisterFactory(String scheme) {
- return factories.unregister(scheme);
+ final ConnectionFactory factory = factories.unregister(scheme);
+
+ if (factory != null){
+ Client.fireEvent(new ConnectionFactoryRemoved(scheme, factory));
+ }
+
+ return factory;
}
public static void registerStrategy(String scheme, ConnectionStrategy factory) {
strategies.register(scheme, factory);
+ Client.fireEvent(new ConnectionStrategyAdded(scheme, factory));
}
public static ConnectionStrategy unregisterStrategy(String scheme) {
- return strategies.unregister(scheme);
+ final ConnectionStrategy strategy = strategies.unregister(scheme);
+
+ if (strategy != null) {
+ Client.fireEvent(new ConnectionStrategyAdded(scheme, strategy));
+ }
+
+ return strategy;
}
/**
@@ -103,4 +147,18 @@ public class ConnectionManager {
public static void setFactory(ConnectionFactory factory) throws IOException {
registerFactory("default", factory);
}
+
+ @Log(Log.Level.SEVERE)
+ public static class UnsupportedConnectionStrategyException extends IOException {
+ public UnsupportedConnectionStrategyException(String message) {
+ super(message);
+ }
+ }
+
+ @Log(Log.Level.SEVERE)
+ public static class UnsupportedConnectionFactoryException extends IOException {
+ public UnsupportedConnectionFactoryException(String message) {
+ super(message);
+ }
+ }
}
Added: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Context.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Context.java?rev=1304198&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Context.java (added)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/Context.java Fri Mar 23 06:18:25 2012
@@ -0,0 +1,42 @@
+/*
+ * 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.openejb.client;
+
+import java.util.HashMap;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class Context {
+
+ private final HashMap<Class, Object> components = new HashMap<Class, Object>();
+
+ @SuppressWarnings({"unchecked"})
+ public <T> T getComponent(Class<T> type) {
+ return (T) components.get(type);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public <T> T setComponent(Class<T> type, T component) {
+ return (T) components.put(type, component);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public <T> T removeComponent(Class<T> type) {
+ return (T) components.remove(type);
+ }
+}
Modified: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java (original)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java Fri Mar 23 06:18:25 2012
@@ -483,14 +483,24 @@ public class EJBRequest implements Clust
return serverHash;
}
+ @Override
public String toString() {
- StringBuilder s = new StringBuilder((requestMethod == null ? "null" : requestMethod.toString()));
- s.append(':').append(deploymentId);
+ final StringBuilder sb = new StringBuilder();
+ sb.append("EJBRequest{");
+ sb.append("deploymentId='");
+ sb.append(deploymentId);
+ sb.append("'");
+
+ if (requestMethod != null) {
+ sb.append(", type=").append(requestMethod);
+ }
if (body != null) {
- s.append(':').append(body.getMethodName());
- s.append(':').append(body.getPrimaryKey());
+ sb.append(", method='").append(body.getMethodName());
+ sb.append("', primaryKey='").append(body.getPrimaryKey());
+ sb.append("'");
}
- return s.toString();
+ sb.append("}");
+ return sb.toString();
}
/*
Added: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EventLogger.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EventLogger.java?rev=1304198&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EventLogger.java (added)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/EventLogger.java Fri Mar 23 06:18:25 2012
@@ -0,0 +1,70 @@
+/*
+ * 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.openejb.client;
+
+import org.apache.openejb.client.event.ClusterMetaDataUpdated;
+import org.apache.openejb.client.event.Log;
+import org.apache.openejb.client.event.Observes;
+
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class EventLogger {
+
+ public void log(@Observes ClusterMetaDataUpdated event) {
+ final Logger logger = Logger.getLogger(event.getClass().getName());
+
+ final ClusterMetaData cluster = event.getClusterMetaData();
+
+ final String msg = event.toString();
+
+ if (logger.isLoggable(Level.FINE)) {
+ logger.log(Level.FINE, msg);
+ }
+
+ if (logger.isLoggable(Level.FINER)) {
+ int i = 0;
+ for (URI uri : cluster.getLocations()) {
+ final String format = String.format("%s #%s %s", msg, ++i, uri.toASCIIString());
+ logger.log(Level.FINER, format);
+ }
+ }
+ }
+
+ public void log(@Observes Object event) {
+ final Log log = event.getClass().getAnnotation(Log.class);
+
+ if (log == null) return;
+
+ final Logger logger = Logger.getLogger(event.getClass().getName());
+
+ try {
+ final Level level = Level.parse(log.value().name());
+
+ if (logger.isLoggable(level)) {
+ logger.log(level, event.toString());
+ }
+
+ } catch (IllegalArgumentException e) {
+ logger.log(Level.WARNING, event.toString());
+ }
+ }
+}
Modified: openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java?rev=1304198&r1=1304197&r2=1304198&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java (original)
+++ openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java Fri Mar 23 06:18:25 2012
@@ -16,6 +16,7 @@
*/
package org.apache.openejb.client;
+import org.apache.openejb.client.event.RemoteInitialContextCreated;
import org.omg.CORBA.ORB;
import javax.naming.AuthenticationException;
@@ -102,7 +103,7 @@ public class JNDIContext implements Init
String providerUrl = (String) env.get(Context.PROVIDER_URL);
moduleId = (String) env.get("openejb.client.moduleId");
- URI location;
+ final URI location;
try {
providerUrl = addMissingParts(providerUrl);
location = new URI(providerUrl);
@@ -110,6 +111,15 @@ public class JNDIContext implements Init
throw (ConfigurationException) new ConfigurationException("Property value for " + Context.PROVIDER_URL + " invalid: " + providerUrl + " - " + e.getMessage()).initCause(e);
}
this.server = new ServerMetaData(location);
+
+ final Client.Context context = Client.getContext(this.server);
+ context.getProperties().putAll(environment);
+
+ final String strategy = context.getOptions().get("openejb.client.connection.strategy", "default");
+ context.getClusterMetaData().setConnectionStrategy(strategy);
+
+ Client.fireEvent(new RemoteInitialContextCreated(location));
+
//TODO:1: Either aggressively initiate authentication or wait for the
// server to send us an authentication challange.
if (userID != null) {