[jboss-cvs] JBossAS SVN: r68599 - in projects/ejb3/trunk: ejb3-socket-inflow and 22 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jan 3 09:22:55 EST 2008


Author: ALRubinger
Date: 2008-01-03 09:22:55 -0500 (Thu, 03 Jan 2008)
New Revision: 68599

Added:
   projects/ejb3/trunk/ejb3-socket-inflow/
   projects/ejb3/trunk/ejb3-socket-inflow/.classpath
   projects/ejb3/trunk/ejb3-socket-inflow/.project
   projects/ejb3/trunk/ejb3-socket-inflow/pom.xml
   projects/ejb3/trunk/ejb3-socket-inflow/src/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/NonBlockingSocketServer.java
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/SocketResourceAdaptor.java
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/RequestHandlingException.java
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/SocketBasedRequestHandler.java
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/http/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/http/CopyHttpRequestToResponseRequestHandler.java
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/inflow/
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/inflow/SocketActivationSpec.java
   projects/ejb3/trunk/ejb3-socket-inflow/src/main/resources/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/socket/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/socket/test/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/socket/test/stress/
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/socket/test/stress/StressSocketServerTestCase.java
   projects/ejb3/trunk/ejb3-socket-inflow/src/test/resources/
Log:
Initial Commit of EJB3 Socket Inflow Adaptor


Property changes on: projects/ejb3/trunk/ejb3-socket-inflow
___________________________________________________________________
Name: svn:ignore
   + target


Added: projects/ejb3/trunk/ejb3-socket-inflow/.classpath
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/.classpath	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/.classpath	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/test/java"/>
+	<classpathentry excluding="**" kind="src" output="src/main/resources" path="src/main/resources"/>
+	<classpathentry excluding="**" kind="src" output="src/test/resources" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: projects/ejb3/trunk/ejb3-socket-inflow/.project
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/.project	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/.project	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>jboss-ejb3-socket-inflow</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: projects/ejb3/trunk/ejb3-socket-inflow/pom.xml
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/pom.xml	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/pom.xml	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  vi:ts=2:sw=2:expandtab:
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <!-- Define Parent -->
+  <parent>
+    <artifactId>jboss-ejb3</artifactId>
+    <groupId>org.jboss.ejb3</groupId>
+    <version>0.12.0-SNAPSHOT</version>
+    <relativePath>../build/pom.xml</relativePath>
+  </parent>
+
+  <!-- Maven POM Model Version -->
+  <modelVersion>4.0.0</modelVersion>
+
+  <!-- Artifact Information -->
+  <groupId>org.jboss</groupId>
+  <artifactId>jboss-ejb3-socket-inflow</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>rar</packaging>
+  <name>JBoss EJB 3.0 Socket Inflow</name>
+  <description>JBoss EJB 3.0 Socket Inflow Adaptor RAR</description>
+  <url>http://labs.jboss.com/jbossejb3/</url>
+
+  <!-- Dependencies -->
+
+  <!-- 
+    
+    Version information is centralized in 
+    the Parent Build POM
+    
+  -->
+
+  <dependencies>
+  
+    <!-- JUnit -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    
+    <!-- These Versions must be moved to the parent POM -->
+    <dependency>
+      <groupId>javax.activation</groupId>
+      <artifactId>activation</artifactId>
+      <version>1.0.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.javaee</groupId>
+      <artifactId>jboss-jca-api</artifactId>
+      <version>1.5.0.Beta3Update1</version>
+    </dependency>
+
+  </dependencies>
+
+</project>
+

Added: projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/NonBlockingSocketServer.java
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/NonBlockingSocketServer.java	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/NonBlockingSocketServer.java	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,314 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.resource.adaptor.socket;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.util.Set;
+
+import org.jboss.ejb3.resource.adaptor.socket.handler.RequestHandlingException;
+import org.jboss.ejb3.resource.adaptor.socket.handler.SocketBasedRequestHandler;
+import org.jboss.logging.Logger;
+
+/**
+ * A Generic Non-Blocking Socket Server with pluggable
+ * request handling implementation
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class NonBlockingSocketServer
+{
+   // Class Members
+
+   /*
+    * Logger
+    */
+   private static final Logger logger = Logger.getLogger(NonBlockingSocketServer.class);
+
+   /*
+    * The Default Port 
+    */
+   public static final int DEFAULT_BIND_PORT = 9001;
+
+   /*
+    * The Default Bind Address 
+    */
+   public static final InetAddress DEFAULT_BIND_HOST;
+   static
+   {
+      try
+      {
+         DEFAULT_BIND_HOST = InetAddress.getLocalHost();
+      }
+      catch (UnknownHostException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   // Instance Members
+
+   private int numberOfConnections;
+
+   private InetSocketAddress bindAddress;
+
+   private boolean running;
+
+   private Selector multiplexor;
+
+   private ServerSocketChannel channel;
+
+   private SocketBasedRequestHandler handler;
+
+   // Constructors
+
+   public NonBlockingSocketServer(SocketBasedRequestHandler handler)
+   {
+      this(NonBlockingSocketServer.DEFAULT_BIND_HOST, NonBlockingSocketServer.DEFAULT_BIND_PORT, handler);
+   }
+
+   public NonBlockingSocketServer(InetAddress bindHost, int bindPort, SocketBasedRequestHandler handler)
+   {
+      // Set as not Running
+      this.setRunning(false);
+
+      // Set Handler
+      this.setHandler(handler);
+
+      // Set Bind Address
+      this.setBindAddress(new InetSocketAddress(bindHost, bindPort));
+
+      // Ensure Valid Bind Address
+      if (this.getBindAddress().isUnresolved())
+      {
+         throw new RuntimeException("Bind Address of " + this.getBindAddress().toString() + " could not be resolved.");
+      }
+   }
+
+   // Functional Methods
+
+   /**
+    * Starts the Server
+    */
+   public void start()
+   {
+      try
+      {
+         // Bind the Server and Register the MultiPlexor
+         this.bindAndRegisterConnection();
+
+         // Set as running
+         this.setRunning(true);
+
+         // Listen for incoming connections
+         this.listenForIncomingConnections();
+
+      }
+      catch (IOException ioe)
+      {
+         throw new RuntimeException(ioe);
+      }
+   }
+
+   /**
+    * Shuts down the Server
+    */
+   public void shutdown()
+   {
+
+      // Set Flag
+      this.setRunning(false);
+
+      // Shutdown
+      this.getMultiplexor().wakeup();
+
+      // Close Channel
+      try
+      {
+         this.getChannel().close();
+      }
+      // Ignore
+      catch (IOException e)
+      {
+      }
+
+      // Log
+      logger.info("Server at " + this.getBindAddress().toString() + " shutdown");
+   }
+
+   // Internal Helper Methods
+
+   /**
+    * Binds the Server to the appropriate binding address and registers
+    * the multiplexor with the underlying communications channel
+    */
+   private void bindAndRegisterConnection() throws IOException
+   {
+      // Create ServerSocketChannel
+      this.setChannel(ServerSocketChannel.open());
+
+      // Set Channel to Non-Blocking IO
+      this.getChannel().configureBlocking(false);
+
+      // Create Multiplexor
+      this.setMultiplexor(this.getChannel().provider().openSelector());
+
+      // Bind Channel to Bind Address 
+      this.getChannel().socket().bind(this.getBindAddress());
+
+      // Register the multiplexor with the channel
+      this.getChannel().register(this.getMultiplexor(), SelectionKey.OP_ACCEPT);
+   }
+
+   /**
+    * Listens for incoming connections and dispatches to the 
+    * Client Request Handler for processing
+    * 
+    * @throws IOException
+    */
+   private void listenForIncomingConnections() throws IOException
+   {
+      // While the server is running
+      while (this.isRunning())
+      {
+         // If new clients have been established
+         if (this.getMultiplexor().select() > 0)
+         {
+            // Record and log new connection
+            this.setNumberOfConnections(this.getNumberOfConnections() + 1);
+            logger.debug("New Connection, Number " + this.getNumberOfConnections());
+
+            // At least one new connection has been requested, obtain the keys
+            Set<SelectionKey> selectionKeys = multiplexor.selectedKeys();
+
+            // For all new selections/clients
+            for (SelectionKey client : selectionKeys)
+            {
+               // Initialize client socket
+               Socket clientSocket = null;
+
+               try
+               {
+                  // Obtain the channel from this client
+                  ServerSocketChannel clientChannel = (ServerSocketChannel) client.channel();
+
+                  // Accept the client channel, and get a reference to its socket                  
+                  clientSocket = clientChannel.accept().socket();
+
+                  // Dispatch to handler
+                  try
+                  {
+                     handler.handleClientRequest(clientSocket);
+                  }
+                  // An error has occurred in processing the request
+                  catch (RequestHandlingException e)
+                  {
+                     throw new RuntimeException(e);
+                  }
+
+               }
+               finally
+               {
+                  // Take this client out of the selection keys so only processed once
+                  selectionKeys.remove(client);
+
+                  // Close
+                  if (clientSocket != null)
+                  {
+                     clientSocket.close();
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   // Accessors / Mutators
+
+   protected InetSocketAddress getBindAddress()
+   {
+      return bindAddress;
+   }
+
+   protected void setBindAddress(InetSocketAddress bindAddress)
+   {
+      this.bindAddress = bindAddress;
+   }
+
+   public boolean isRunning()
+   {
+      return running;
+   }
+
+   protected void setRunning(boolean running)
+   {
+      this.running = running;
+   }
+
+   protected Selector getMultiplexor()
+   {
+      return multiplexor;
+   }
+
+   protected void setMultiplexor(Selector multiplexor)
+   {
+      this.multiplexor = multiplexor;
+   }
+
+   protected ServerSocketChannel getChannel()
+   {
+      return channel;
+   }
+
+   protected void setChannel(ServerSocketChannel channel)
+   {
+      this.channel = channel;
+   }
+
+   protected SocketBasedRequestHandler getHandler()
+   {
+      return handler;
+   }
+
+   protected void setHandler(SocketBasedRequestHandler handler)
+   {
+      this.handler = handler;
+   }
+
+   public int getNumberOfConnections()
+   {
+      return numberOfConnections;
+   }
+
+   protected void setNumberOfConnections(int numberOfConnections)
+   {
+      this.numberOfConnections = numberOfConnections;
+   }
+
+}

Added: projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/SocketResourceAdaptor.java
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/SocketResourceAdaptor.java	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/SocketResourceAdaptor.java	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.resource.adaptor.socket;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.BootstrapContext;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterInternalException;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.resource.spi.work.Work;
+import javax.resource.spi.work.WorkException;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.ejb3.resource.adaptor.socket.handler.http.CopyHttpRequestToResponseRequestHandler;
+import org.jboss.ejb3.resource.adaptor.socket.inflow.SocketActivationSpec;
+
+public class SocketResourceAdaptor implements ResourceAdapter, Work
+{
+   // Instance Members
+   /*
+    * Bootstrap Context
+    */
+   private BootstrapContext ctx;
+
+   /*
+    * Server to handle AJAX Requests
+    */
+   private NonBlockingSocketServer server;
+
+   /*
+    * ActivationSpec / MessageEndpoint Factories 
+    */
+   private ConcurrentMap<ActivationSpec, MessageEndpointFactory> activationSpecFactories = new ConcurrentHashMap<ActivationSpec, MessageEndpointFactory>();
+
+   // Accessors / Mutators
+   public BootstrapContext getCtx()
+   {
+      return ctx;
+   }
+
+   public void setCtx(BootstrapContext ctx)
+   {
+      this.ctx = ctx;
+   }
+
+   private NonBlockingSocketServer getServer()
+   {
+      return server;
+   }
+
+   private void setServer(NonBlockingSocketServer server)
+   {
+      this.server = server;
+   }
+
+   private Map<ActivationSpec, MessageEndpointFactory> getActivationSpecFactories()
+   {
+      return activationSpecFactories;
+   }
+
+   // ResourceAdaptor Required Implementations
+
+   public void endpointActivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec)
+         throws ResourceException
+   {
+      // Initialize
+      Class<?> activationSpecType = SocketActivationSpec.class;
+      // Ensure assignable
+      if (!(activationSpecType.isAssignableFrom(activationSpec.getClass())))
+      {
+         throw new ResourceException("Supplied ActivationSpec must be of type " + activationSpecType.getName()
+               + "; is instead of type " + activationSpec.getClass().getName());
+      }
+      // Place Activation Spec into factories
+      this.getActivationSpecFactories().put(activationSpec, messageEndpointFactory);
+   }
+
+   public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec)
+   {
+      // Remove ActivationSpec from factories
+      this.getActivationSpecFactories().remove(activationSpec);
+   }
+
+   public XAResource[] getXAResources(ActivationSpec[] activationSpec) throws ResourceException
+   {
+      // Null
+      return null;
+   }
+
+   public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException
+   {
+      // Set Context
+      this.setCtx(bootstrapContext);
+
+      // Create new Server
+      try
+      {
+         //TODO Handler from ActivationConfig properties
+         this.setServer(new NonBlockingSocketServer(CopyHttpRequestToResponseRequestHandler.class.newInstance()));
+      }
+      catch (InstantiationException e)
+      {
+         throw new ResourceAdapterInternalException(e);
+      }
+      catch (IllegalAccessException e)
+      {
+         throw new ResourceAdapterInternalException(e);
+      }
+
+      // Start the Server in own Thread
+      try
+      {
+         this.getCtx().getWorkManager().startWork(this);
+      }
+      catch (WorkException e)
+      {
+         throw new ResourceAdapterInternalException(e);
+      }
+   }
+
+   public void stop()
+   {
+      // Delegate to Work's "release"
+      this.release();
+   }
+
+   // Work Required Implementations
+
+   public void run()
+   {
+      // Start the Server
+      this.getServer().start();
+   }
+
+   public void release()
+   {
+      // Shutdown the Server
+      this.getServer().shutdown();
+   }
+}
\ No newline at end of file

Added: projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/RequestHandlingException.java
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/RequestHandlingException.java	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/RequestHandlingException.java	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.resource.adaptor.socket.handler;
+
+/**
+ * Exception thrown when an error is encountered
+ * while servicing a client request
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class RequestHandlingException extends Exception
+{
+   // Class Members
+   private static final long serialVersionUID = 776718948465190971L;
+
+   // Constructors
+   public RequestHandlingException()
+   {
+      super();
+   }
+
+   public RequestHandlingException(String message, Throwable cause)
+   {
+      super(message, cause);
+   }
+
+   public RequestHandlingException(String message)
+   {
+      super(message);
+   }
+
+   public RequestHandlingException(Throwable cause)
+   {
+      super(cause);
+   }
+
+}

Added: projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/SocketBasedRequestHandler.java
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/SocketBasedRequestHandler.java	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/SocketBasedRequestHandler.java	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.resource.adaptor.socket.handler;
+
+import java.net.Socket;
+
+/**
+ * Contract defining how socket-bsaed requests from a client
+ * may be implemented
+ * 
+ * @author <a href="mailto:andrew.rubinger at redhat.com">ALR</a>
+ * @version $Revision: $
+ */
+public interface SocketBasedRequestHandler
+{
+   /**
+    * Services the client request represented by the specified
+    * socket.  Typical implementations may read in request data,
+    * perform appropriate processing, and write the response, closing
+    * the socket when complete.  
+    * 
+    * @param socket
+    * @throws RequestHandlingException
+    */
+   void handleClientRequest(Socket socket) throws RequestHandlingException;
+}

Added: projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/http/CopyHttpRequestToResponseRequestHandler.java
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/http/CopyHttpRequestToResponseRequestHandler.java	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/handler/http/CopyHttpRequestToResponseRequestHandler.java	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.resource.adaptor.socket.handler.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import org.jboss.ejb3.resource.adaptor.socket.handler.RequestHandlingException;
+import org.jboss.ejb3.resource.adaptor.socket.handler.SocketBasedRequestHandler;
+
+/**
+ * Request Handler implementation to read in the client request and 
+ * echo it as a response.  Mostly used in testing without practical application.
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class CopyHttpRequestToResponseRequestHandler implements SocketBasedRequestHandler
+{
+
+   // Class Members
+   /*
+    * Byte Pattern designating HTTP Request EOF
+    */
+   public static final byte[] HTTP_REQUEST_EOF = "\r\n\r\n".getBytes();
+
+   // Required Implementations
+
+   /**
+    * Reads in the client request and mirrors the content in the response
+    * 
+    * @param clientSocket
+    * @throws RequestHandlingException
+    */
+   public void handleClientRequest(Socket clientSocket) throws RequestHandlingException
+   {
+      // Initialize Streams
+      OutputStream outStream = null;
+      InputStream inStream = null;
+
+      // Obtain Streams
+      try
+      {
+         outStream = clientSocket.getOutputStream();
+         inStream = clientSocket.getInputStream();
+
+         // Copy request content to response
+         byte[] buffer = new byte[1024];
+         int i = 0;
+         while ((i = inStream.read(buffer)) != -1)
+         {
+            outStream.write(buffer);
+
+            // If HTTP EOF is encountered
+            if (CopyHttpRequestToResponseRequestHandler.indexOf(buffer,
+                  CopyHttpRequestToResponseRequestHandler.HTTP_REQUEST_EOF) != -1)
+            {
+               // Stop
+               break;
+            }
+         }
+      }
+      catch (IOException ioe)
+      {
+         throw new RuntimeException(ioe);
+      }
+   }
+
+   /**
+    * Returns the index of the specified pattern to find in the specified byte array, 
+    * or -1 if not found 
+    * 
+    * @param arrayToSearch
+    * @param patternToFind
+    * @return
+    */
+   //TODO Should be centralized to I/O Utility
+   private static int indexOf(byte[] arrayToSearch, byte[] patternToFind)
+   {
+      String toSearch = new String(arrayToSearch);
+      String toFind = new String(patternToFind);
+      return toSearch.indexOf(toFind);
+   }
+}
\ No newline at end of file

Added: projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/inflow/SocketActivationSpec.java
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/inflow/SocketActivationSpec.java	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/src/main/java/org/jboss/ejb3/resource/adaptor/socket/inflow/SocketActivationSpec.java	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,169 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.resource.adaptor.socket.inflow;
+
+import java.io.Serializable;
+import java.net.InetSocketAddress;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.InvalidPropertyException;
+import javax.resource.spi.ResourceAdapter;
+
+import org.jboss.ejb3.resource.adaptor.socket.SocketResourceAdaptor;
+
+/**
+ * Activation Specification for Socket-based Inflow
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class SocketActivationSpec implements ActivationSpec, Serializable
+{
+   // Class Members
+   
+   /*
+    * Serial Version UID
+    */
+   private static final long serialVersionUID = 5427084615487469213L;
+
+   // Instance Members
+
+   /*
+    * ResourceAdaptor
+    */
+   private SocketResourceAdaptor resourceAdaptor;
+
+   /*
+    * Address upon which to bind Server to listen for incoming AJAX Requests
+    */
+   private String bindAddress;
+
+   /*
+    * Port upon which to bind Server to listen for incoming AJAX Requests
+    */
+   private int port;
+
+   /*
+    * Handler to Service incoming client requests 
+    */
+   private String handlerClassName;
+
+   // ActivationSpec Required Implementations
+   public void validate() throws InvalidPropertyException
+   {
+      // Ensure Bind Address is Specified
+      if (this.getBindAddress() == null || this.getBindAddress().equals(""))
+      {
+         throw new InvalidPropertyException("ActivationSpec Property 'bindAddress' is required");
+      }
+      // Ensure Port is specified
+      if (this.getPort() == 0)
+      {
+         throw new InvalidPropertyException("ActivationSpec Property 'port' is required");
+      }
+
+      // Ensure Handler is specified
+      if (this.getHandlerClassName() == null || this.getHandlerClassName().equals(""))
+      {
+         throw new InvalidPropertyException("ActivationSpec Property 'handlerClassName' is required");
+      }
+
+      // Ensure Handler is Valid
+      try
+      {
+         Class.forName(this.getHandlerClassName()).newInstance();
+      }
+      catch (InstantiationException e)
+      {
+         throw new InvalidPropertyException(e);
+      }
+      catch (IllegalAccessException e)
+      {
+         throw new InvalidPropertyException(e);
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new InvalidPropertyException(e);
+      }
+
+      // Create an InetSocketAddress to ensure binding is possible to properties specified
+      InetSocketAddress address = new InetSocketAddress(this.getBindAddress(), this.getPort());
+      // Ensure binding succeeds
+      if (address.isUnresolved())
+      {
+         throw new InvalidPropertyException("Cannot bind to " + address.toString());
+      }
+   }
+
+   public ResourceAdapter getResourceAdapter()
+   {
+      return this.resourceAdaptor;
+   }
+
+   public void setResourceAdapter(ResourceAdapter resourceAdaptor) throws ResourceException
+   {
+      this.resourceAdaptor = (SocketResourceAdaptor) resourceAdaptor;
+   }
+
+   // Accessors / Mutators
+   
+   protected SocketResourceAdaptor getResourceAdaptor()
+   {
+      return resourceAdaptor;
+   }
+
+   protected void setResourceAdaptor(SocketResourceAdaptor resourceAdaptor)
+   {
+      this.resourceAdaptor = resourceAdaptor;
+   }
+
+   protected String getBindAddress()
+   {
+      return bindAddress;
+   }
+
+   protected void setBindAddress(String bindAddress)
+   {
+      this.bindAddress = bindAddress;
+   }
+
+   protected int getPort()
+   {
+      return port;
+   }
+
+   protected void setPort(int port)
+   {
+      this.port = port;
+   }
+
+   protected String getHandlerClassName()
+   {
+      return handlerClassName;
+   }
+
+   protected void setHandlerClassName(String handler)
+   {
+      this.handlerClassName = handler;
+   }
+}
\ No newline at end of file

Added: projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/socket/test/stress/StressSocketServerTestCase.java
===================================================================
--- projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/socket/test/stress/StressSocketServerTestCase.java	                        (rev 0)
+++ projects/ejb3/trunk/ejb3-socket-inflow/src/test/java/org/jboss/ejb3/resource/adaptor/socket/test/stress/StressSocketServerTestCase.java	2008-01-03 14:22:55 UTC (rev 68599)
@@ -0,0 +1,323 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.resource.adaptor.socket.test.stress;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+import org.jboss.ejb3.resource.adaptor.socket.NonBlockingSocketServer;
+import org.jboss.ejb3.resource.adaptor.socket.handler.http.CopyHttpRequestToResponseRequestHandler;
+import org.junit.Test;
+
+/**
+ * Test Cases for Stressing the Generic POJO Socket Server
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class StressSocketServerTestCase extends TestCase
+{
+   // Instance Members
+
+   /*
+    * The Server Thread
+    */
+   private ServerThread serverThread = null;
+
+   /*
+    * A collection of pending requests requiring servicing 
+    */
+   private static final Collection<String> requestsPending = Collections
+         .synchronizedCollection(new ArrayList<String>());
+
+   // Test Methods
+   @Test
+   public void testStress50ConcurrentRequests()
+   {
+      this.runStressTest(50);
+   }
+
+   @Test
+   public void testStress200ConcurrentRequests()
+   {
+      this.runStressTest(200);
+   }
+
+   @Test
+   public void testStress500ConcurrentRequests()
+   {
+      this.runStressTest(500);
+   }
+
+   @Test
+   public void testStress1000ConcurrentRequests()
+   {
+      this.runStressTest(1000);
+   }
+
+   @Test
+   public void testStress1500ConcurrentRequests()
+   {
+      this.runStressTest(1500);
+   }
+
+   // Overridden Implementations
+   /**
+    * Setup
+    */
+   @Override
+   protected void setUp() throws Exception
+   {
+      // Call super implementation
+      super.setUp();
+      // Create a new Server
+      if (this.serverThread == null)
+      {
+         this.serverThread = new ServerThread();
+      }
+      // Start the ServerThread
+      this.serverThread.start();
+      // Block until Server is running
+      while (this.serverThread.getServer() == null || !this.serverThread.getServer().isRunning())
+      {
+         Thread.sleep(10);
+      }
+      // Log Started
+      System.out.println("Server Started");
+   }
+
+   /**
+    * Tear Down
+    */
+   @Override
+   protected void tearDown() throws Exception
+   {
+      // Call super Implementation
+      super.tearDown();
+
+      // Shutdown the Server
+      this.serverThread.shutdown();
+
+      // Block until Server Thread is dead
+      while (this.serverThread.isAlive())
+      {
+
+      }
+
+      // Log Shutdown
+      System.out.println("Server Shutdown\n");
+   }
+
+   // Inner Classes
+
+   /**
+    * Creates a new Client HTTP Request in its own Thread of execution
+    * 
+    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+    * @version $Revision: $
+    */
+   private static class ClientThread extends Thread implements Runnable
+   {
+      // Instance Members
+      String testString;
+
+      // Constructor
+      public ClientThread(String testString)
+      {
+         this.testString = testString;
+         this.setName("Client Thread (Request " + testString + "");
+      }
+
+      // Overridden Implementations
+      @Override
+      public void run()
+      {
+         // Call Super Implementation
+         super.run();
+
+         // Run the Test
+         try
+         {
+            this.runTest();
+         }
+         catch (IOException e)
+         {
+            throw new RuntimeException(e);
+         }
+      }
+
+      public void runTest() throws IOException
+      {
+         // Create new Socket
+         Socket socket = new Socket(NonBlockingSocketServer.DEFAULT_BIND_HOST,
+               NonBlockingSocketServer.DEFAULT_BIND_PORT);
+
+         // Create a Writer for the request
+         PrintWriter writer = new PrintWriter(socket.getOutputStream());
+
+         // Obtain a Reader for the response
+         InputStreamReader reader = new InputStreamReader(socket.getInputStream());
+
+         // Write the request to the Server
+         writer.print(testString + new String(CopyHttpRequestToResponseRequestHandler.HTTP_REQUEST_EOF));
+         writer.flush();
+         //System.out.println("SENT: " + testString);
+
+         // Read in the response
+         char[] buffer = new char[1024];
+         int i = 0;
+         StringBuffer sb = new StringBuffer();
+         while ((i = reader.read(buffer)) != -1)
+         {
+            sb.append(buffer);
+         }
+
+         // Parse the response
+         String responseStringReceived = sb.toString().trim();
+
+         // Remove this from the pending requests
+         StressSocketServerTestCase.requestsPending.remove(responseStringReceived);
+
+         // Log Response
+         //System.out.println("RECEIVED: " + responseStringReceived);
+
+         // Close the Client Socket
+         socket.close();
+      }
+   }
+
+   /**
+    * Starts the Server in a separate process
+    * 
+    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+    * @version $Revision: $
+    */
+   private static class ServerThread extends Thread implements Runnable
+   {
+      // Instance Members
+
+      private NonBlockingSocketServer server;
+
+      // Constructor
+
+      public ServerThread()
+      {
+         this.setName("Server");
+      }
+
+      // Overridden Implementations
+
+      @Override
+      public void run()
+      {
+         // Call super implementation
+         super.run();
+         // Create new Server
+         this.setServer(new NonBlockingSocketServer(new CopyHttpRequestToResponseRequestHandler()));
+         // Start Server
+         this.getServer().start();
+      }
+
+      // Functional Methods
+      public void shutdown()
+      {
+         // Delegate to Server to shutdown
+         this.getServer().shutdown();
+
+         // Block until shutdown
+         while (this.getServer().isRunning())
+         {
+
+         }
+
+         // Stop Thread
+         this.interrupt();
+      }
+
+      // Accessors / Mutators
+      private NonBlockingSocketServer getServer()
+      {
+         return server;
+      }
+
+      private void setServer(NonBlockingSocketServer server)
+      {
+         this.server = server;
+      }
+   }
+
+   // Internal Helper Methods
+
+   private void runStressTest(int numberOfRequests)
+   {
+      // Log
+      System.out.println("Starting Stress Test for " + numberOfRequests + " Concurrent Requests...");
+      // Initialize
+      Collection<ClientThread> clients = new ArrayList<ClientThread>();
+      // For each of the requests to make
+      for (int i = 0; i < numberOfRequests; i++)
+      {
+         // Create a unique request String
+         String requestString = "TEST " + i;
+         // Add to the list of requests
+         StressSocketServerTestCase.requestsPending.add(requestString);
+         // Make a new Client for this request
+         clients.add(new ClientThread(requestString));
+      }
+      // Record start time
+      long startTime = System.currentTimeMillis();
+      // Run all clients
+      for (ClientThread client : clients)
+      {
+         client.start();
+      }
+      // Block until all requests are serviced and received
+      while (StressSocketServerTestCase.requestsPending.size() > 0)
+      {
+      }
+
+      // Record end time
+      long endTime = System.currentTimeMillis();
+
+      // Calculate total time
+      float totalTime = endTime - startTime;
+      float seconds = (float) totalTime / (float) 1000;
+
+      // Log
+      System.out.println(numberOfRequests + " Requests Serviced in " + totalTime + "ms (" + seconds + " seconds)");
+      System.out.println(totalTime + "ms  / " + numberOfRequests + " Requests = " + (totalTime / numberOfRequests)
+            + "ms Average Per Request");
+
+      // Shutdown all clients
+      for (ClientThread client : clients)
+      {
+         client.interrupt();
+      }
+   }
+}




More information about the jboss-cvs-commits mailing list