[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