Return-Path: X-Original-To: apmail-tomee-commits-archive@www.apache.org Delivered-To: apmail-tomee-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2C6F71093C for ; Mon, 12 Aug 2013 10:17:27 +0000 (UTC) Received: (qmail 20525 invoked by uid 500); 12 Aug 2013 10:17:26 -0000 Delivered-To: apmail-tomee-commits-archive@tomee.apache.org Received: (qmail 20466 invoked by uid 500); 12 Aug 2013 10:17:26 -0000 Mailing-List: contact commits-help@tomee.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tomee.apache.org Delivered-To: mailing list commits@tomee.apache.org Received: (qmail 20459 invoked by uid 99); 12 Aug 2013 10:17:25 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 12 Aug 2013 10:17:25 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 12 Aug 2013 10:17:18 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 51FBC238888A; Mon, 12 Aug 2013 10:16:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1513095 - in /tomee/tomee/trunk: itests/ itests/legacy-client/ itests/legacy-client/src/test/java/org/apache/openejb/itest/legacy/ itests/legacy-server/ itests/legacy-server/src/ itests/legacy-server/src/main/ itests/legacy-server/src/test... Date: Mon, 12 Aug 2013 10:16:55 -0000 To: commits@tomee.apache.org From: andygumbrecht@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130812101656.51FBC238888A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: andygumbrecht Date: Mon Aug 12 10:16:54 2013 New Revision: 1513095 URL: http://svn.apache.org/r1513095 Log: Added client system property "openejb.client.protocol.version" to allow new (4.6.x) OpenEJB clients to communicate with old (4.5.2) servers, with legacy test. Added: tomee/tomee/trunk/itests/legacy-server/ (with props) tomee/tomee/trunk/itests/legacy-server/pom.xml tomee/tomee/trunk/itests/legacy-server/src/ tomee/tomee/trunk/itests/legacy-server/src/main/ tomee/tomee/trunk/itests/legacy-server/src/test/ tomee/tomee/trunk/itests/legacy-server/src/test/java/ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/ClientThread.java tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/LegacyServerTest.java Modified: tomee/tomee/trunk/itests/legacy-client/pom.xml tomee/tomee/trunk/itests/legacy-client/src/test/java/org/apache/openejb/itest/legacy/LegacyClientTest.java tomee/tomee/trunk/itests/pom.xml tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/AuthenticationRequest.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterRequest.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBInvocationHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIRequest.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Request.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Response.java Modified: tomee/tomee/trunk/itests/legacy-client/pom.xml URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/itests/legacy-client/pom.xml?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/itests/legacy-client/pom.xml (original) +++ tomee/tomee/trunk/itests/legacy-client/pom.xml Mon Aug 12 10:16:54 2013 @@ -28,7 +28,7 @@ org.apache.openejb.itests legacy-client jar - OpenEJB :: iTests :: Legacy + OpenEJB :: iTests :: Legacy Client Modified: tomee/tomee/trunk/itests/legacy-client/src/test/java/org/apache/openejb/itest/legacy/LegacyClientTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/itests/legacy-client/src/test/java/org/apache/openejb/itest/legacy/LegacyClientTest.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/itests/legacy-client/src/test/java/org/apache/openejb/itest/legacy/LegacyClientTest.java (original) +++ tomee/tomee/trunk/itests/legacy-client/src/test/java/org/apache/openejb/itest/legacy/LegacyClientTest.java Mon Aug 12 10:16:54 2013 @@ -70,7 +70,7 @@ public class LegacyClientTest { // System.setProperty("version", OpenEjbVersion.get().getVersion()); System.setProperty("openejb.client.connection.strategy", "roundrobin"); - logger.info("Retrieving standalone server: " + Repository.guessVersion("org.apache.openejb", "openejb-standalone")); + logger.info("Retrieving standalone server: " + Repository.guessVersion("org.apache.openejb", "openejb-standalone") + " - This may take a while..."); final File zip = Repository.getArtifact("org.apache.openejb", "openejb-standalone", "zip"); final File app = Repository.getArtifact("org.apache.openejb.itests", "failover-ejb", "jar"); Propchange: tomee/tomee/trunk/itests/legacy-server/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Aug 12 10:16:54 2013 @@ -0,0 +1,2 @@ +*.iml +target Added: tomee/tomee/trunk/itests/legacy-server/pom.xml URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/itests/legacy-server/pom.xml?rev=1513095&view=auto ============================================================================== --- tomee/tomee/trunk/itests/legacy-server/pom.xml (added) +++ tomee/tomee/trunk/itests/legacy-server/pom.xml Mon Aug 12 10:16:54 2013 @@ -0,0 +1,62 @@ + + + + + + itests + org.apache.openejb + 4.6.0-SNAPSHOT + + + 4.0.0 + org.apache.openejb.itests + legacy-server + jar + OpenEJB :: iTests :: Legacy Server + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + 4.5.2 + 3.1 + + + + + + + + + org.apache.openejb.itests + failover + ${project.version} + + + junit + junit + compile + + + + + Added: tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/ClientThread.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/ClientThread.java?rev=1513095&view=auto ============================================================================== --- tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/ClientThread.java (added) +++ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/ClientThread.java Mon Aug 12 10:16:54 2013 @@ -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.legacy; + +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(final Callable callable) { + this.callable = callable; + } + + @Override + public void run() { + while (run.get()) { + pause(); + + try { + callable.call(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public ClientThread delay(final long delay){ + setDelay(delay); + return this; + } + + public void setDelay(final 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; + } +} Added: tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/LegacyServerTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/LegacyServerTest.java?rev=1513095&view=auto ============================================================================== --- tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/LegacyServerTest.java (added) +++ tomee/tomee/trunk/itests/legacy-server/src/test/java/org/apache/openejb/itest/legacy/LegacyServerTest.java Mon Aug 12 10:16:54 2013 @@ -0,0 +1,335 @@ +/* + * 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.legacy; + +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.Repository; +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 LegacyServerTest { + + 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", OpenEjbVersion.get().getVersion()); + System.setProperty("openejb.client.connection.strategy", "roundrobin"); + + logger.info("Retrieving standalone server: " + Repository.guessVersion("org.apache.openejb", "openejb-standalone") + " - This may take a while..."); + 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.getJvmOpts().add("-Dopenejb.classloader.forced-load=org.apache.openejb"); + 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 servers = new HashMap(); + for (final 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"); + server.getJvmOpts().add("-Dopenejb.classloader.forced-load=org.apache.openejb"); + + IO.copy(app, Files.path(home, "apps", "itest.jar")); + IO.copy(IO.read(""), 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 (final Map.Entry 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(30, 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 (final Map.Entry 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(30, TimeUnit.SECONDS, new CalculatorCallable(bean), 500); + + logger.info("Asserting balance"); + assertBalance(bean, services.get().size()); + } + } + + private void assertBalance(final Calculator bean, final int size) { + final int expectedInvocations = 1000; + final double percent = 0.10; + final int totalInvocations = size * expectedInvocations; + + // Verify the work reached all servers + final Set> entries = invoke(bean, totalInvocations).entrySet(); + + Assert.assertEquals(size, entries.size()); + + // And each server got a minimum of %10 percent of the traffic + for (final Map.Entry 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 invoke(final Calculator bean, final int max) { + final Map invocations = new HashMap(); + 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 (final Map.Entry 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 expected = new HashSet(); + + public Services() { + } + + public Set get() { + return expected; + } + + public boolean add(final URI uri) { + return expected.add(uri); + } + + public boolean remove(final URI o) { + return expected.remove(o); + } + + public void observe(@Observes final ClusterMetaDataUpdated updated) { + final URI[] locations = updated.getClusterMetaData().getLocations(); + final Set found = new HashSet(Arrays.asList(locations)); + + if (expected.equals(found)) { + lock.lock(); + try { + condition.signal(); + } finally { + lock.unlock(); + } + } + } + + public Set diff(final Set a, final Set b) { + final Set diffs = new HashSet(); + for (final URI uri : b) { + if (!a.contains(uri)) { + diffs.add(uri); + } + } + + return diffs; + } + + public void assertServices(final long timeout, final TimeUnit unit, final Callable callable) { + assertServices(timeout, unit, callable, 10); + } + + public void assertServices(final long timeout, final TimeUnit unit, final Callable callable, final 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(final long timeout, final 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(final Calculator bean) { + this.bean = bean; + } + + @Override + public Object call() throws Exception { + Assert.assertEquals(3, bean.sum(1, 2)); + return bean.name(); + } + } +} Modified: tomee/tomee/trunk/itests/pom.xml URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/itests/pom.xml?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/itests/pom.xml (original) +++ tomee/tomee/trunk/itests/pom.xml Mon Aug 12 10:16:54 2013 @@ -36,6 +36,7 @@ failover failover-ejb legacy-client + legacy-server openejb-itests-app openejb-itests-beans openejb-itests-client Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/AuthenticationRequest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/AuthenticationRequest.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/AuthenticationRequest.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/AuthenticationRequest.java Mon Aug 12 10:16:54 2013 @@ -40,6 +40,7 @@ public class AuthenticationRequest imple this.credentials = credentials; } + @Override public void setMetaData(final ProtocolMetaData metaData) { this.metaData = metaData; } @@ -61,6 +62,9 @@ public class AuthenticationRequest imple return credentials; } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final byte version = in.readByte(); // future use @@ -70,6 +74,9 @@ public class AuthenticationRequest imple credentials = (String) in.readObject(); } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @Override public void writeExternal(final ObjectOutput out) throws IOException { // write out the version of the serialized data for future use Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Client.java Mon Aug 12 10:16:54 2013 @@ -50,16 +50,26 @@ import static org.apache.openejb.client. public class Client { + public static final String OPENEJB_CLIENT_RETRY_CONDITION_MAX = "openejb.client.retry.condition.max"; + private static final String OPENEJB_CLIENT_COMPATIBILITY_VERSION = "openejb.client.protocol.version"; + private static final Logger logger = Logger.getLogger("OpenEJB.client"); private boolean FINEST = logger.isLoggable(Level.FINEST); private boolean FINER = logger.isLoggable(Level.FINER); public static final ThreadLocal> failed = new ThreadLocal>(); private static final ProtocolMetaData PROTOCOL_META_DATA = new ProtocolMetaData(); - private static final int maxConditionRetry = Integer.parseInt(System.getProperty("openejb.client.retry.condition.max", "20")); - private List> retryConditions = new CopyOnWriteArrayList>(); + private static final int maxConditionRetry = Integer.parseInt(System.getProperty(OPENEJB_CLIENT_RETRY_CONDITION_MAX, "20")); private static Client client = new Client(); + private static final ProtocolMetaData COMPATIBLE_META_DATA; + + static { + final String version = System.getProperty(OPENEJB_CLIENT_COMPATIBILITY_VERSION); + COMPATIBLE_META_DATA = (null != version ? new ProtocolMetaData(version) : null); + } + + private List> retryConditions = new CopyOnWriteArrayList>(); private boolean retry = false; private final Observers observers = new Observers(); @@ -234,6 +244,7 @@ public class Client { /*----------------------------------*/ try { + req.setMetaData(COMPATIBLE_META_DATA); req.writeExternal(objectOut); objectOut.flush(); out.flush(); Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterRequest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterRequest.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterRequest.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ClusterRequest.java Mon Aug 12 10:16:54 2013 @@ -35,6 +35,7 @@ public class ClusterRequest implements R clusterMetaDataVersion = clusterMetaData.getVersion(); } + @Override public void setMetaData(final ProtocolMetaData metaData) { this.metaData = metaData; } @@ -48,11 +49,17 @@ public class ClusterRequest implements R return clusterMetaDataVersion; } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { clusterMetaDataVersion = in.readLong(); } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @Override public void writeExternal(final ObjectOutput out) throws IOException { out.writeLong(clusterMetaDataVersion); Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBInvocationHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBInvocationHandler.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBInvocationHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBInvocationHandler.java Mon Aug 12 10:16:54 2013 @@ -35,6 +35,7 @@ import java.lang.reflect.Method; import java.rmi.AccessException; import java.rmi.NoSuchObjectException; import java.rmi.RemoteException; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -86,7 +87,11 @@ public abstract class EJBInvocationHandl remote = remoteInterface != null && (EJBObject.class.isAssignableFrom(remoteInterface) || EJBHome.class.isAssignableFrom(remoteInterface)); } - public EJBInvocationHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final Object primaryKey, JNDIContext.AuthenticationInfo auth) { + public EJBInvocationHandler(final EJBMetaDataImpl ejb, + final ServerMetaData server, + final ClientMetaData client, + final Object primaryKey, + final JNDIContext.AuthenticationInfo auth) { this(ejb, server, client, auth); this.primaryKey = primaryKey; } @@ -113,7 +118,8 @@ public abstract class EJBInvocationHandl return c.getMethod(method, params); } catch (NoSuchMethodException nse) { throw new IllegalStateException("Cannot find method: " + c.getName() + "." + method, nse); - + } catch (java.lang.ExceptionInInitializerError eiie) { + throw new IllegalStateException("Invalid parameters for method: " + c.getName() + "." + method + " : " + Arrays.toString(params), eiie); } } Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java Mon Aug 12 10:16:54 2013 @@ -43,6 +43,7 @@ import java.util.concurrent.atomic.Atomi import java.util.logging.Level; import java.util.logging.Logger; +@SuppressWarnings("NullArgumentToVariableArgMethod") public abstract class EJBObjectHandler extends EJBInvocationHandler { public static final String OPENEJB_CLIENT_INVOKER_THREADS = "openejb.client.invoker.threads"; Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBRequest.java Mon Aug 12 10:16:54 2013 @@ -75,6 +75,7 @@ public class EJBRequest implements Clust setPrimaryKey(primaryKey); } + @Override public void setMetaData(final ProtocolMetaData metaData) { this.metaData = metaData; this.body.setMetaData(this.metaData); @@ -235,14 +236,14 @@ public class EJBRequest implements Clust return sb.toString(); } - /* - When the Request externalizes itself, it will reset - the appropriate values so that this instance can be used - again. - - There will be one request instance for each handler - */ - + /** + * Changes to this method must observe the optional {@link #metaData} version + *

+ * When the Request externalizes itself, it will reset + * the appropriate values so that this instance can be used again. + *

+ * There will be one request instance for each handler + */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { ClassNotFoundException ex = null; @@ -417,6 +418,9 @@ public class EJBRequest implements Clust this.requestId = requestId; } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @SuppressWarnings("unchecked") @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { @@ -468,6 +472,9 @@ public class EJBRequest implements Clust } } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @Override public void writeExternal(final ObjectOutput out) throws IOException { @@ -488,6 +495,9 @@ public class EJBRequest implements Clust } } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ protected void writeMethodParameters(final ObjectOutput out, final Class[] types, final Object[] args) throws IOException { out.writeByte(types.length); @@ -585,6 +595,9 @@ public class EJBRequest implements Clust return orb; } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ protected void readMethodParameters(final ObjectInput in) throws IOException, ClassNotFoundException { final int length = in.read(); Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIRequest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIRequest.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIRequest.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIRequest.java Mon Aug 12 10:16:54 2013 @@ -36,6 +36,7 @@ public class JNDIRequest implements Clus this.requestString = requestString; } + @Override public void setMetaData(final ProtocolMetaData metaData) { this.metaData = metaData; } @@ -79,6 +80,9 @@ public class JNDIRequest implements Clus return serverHash; } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final byte version = in.readByte(); // future use @@ -94,6 +98,9 @@ public class JNDIRequest implements Clus serverHash = in.readInt(); } + /** + * Changes to this method must observe the optional {@link #metaData} version + */ @Override public void writeExternal(final ObjectOutput out) throws IOException { // write out the version of the serialized data for future use Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java Mon Aug 12 10:16:54 2013 @@ -48,6 +48,10 @@ public class ProtocolMetaData implements init(OEJB + "/" + VERSION); } + public ProtocolMetaData(final String version) { + init(OEJB + "/" + version); + } + private void init(final String spec) { if (!spec.matches("^OEJP/[0-9]\\.[0-9]$")) { Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Request.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Request.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Request.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Request.java Mon Aug 12 10:16:54 2013 @@ -25,6 +25,13 @@ public interface Request extends Externa public RequestType getRequestType(); + /** + * Set the protocol metadata that can be used for versioned requests + * + * @param metaData ProtocolMetaData + */ + public void setMetaData(final ProtocolMetaData metaData); + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException; Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Response.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Response.java?rev=1513095&r1=1513094&r2=1513095&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Response.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/Response.java Mon Aug 12 10:16:54 2013 @@ -26,7 +26,7 @@ public interface Response extends Extern /** * Set the protocol metadata that can be used for version checking * - * @param metaData + * @param metaData ProtocolMetaData */ public void setMetaData(final ProtocolMetaData metaData);