Revision: 31
Author:
perica.m...@gmail.com
Date: Sat Dec 1 15:14:30 2012
Log: netty support by chobicus
http://code.google.com/p/mozzes/source/detail?r=31
Added:
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingClient/src/main/java/org/mozzes/application/remoting/client/NettyRemoteClientConfiguration.java
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/NettyRemotingPlugin.java
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/NettyRemotingServerListener.java
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingExecutorsPlugin.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/MozzesClientHandler.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/MozzesClientPipelineFactory.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/NettyRemotingClient.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/NettyRemotingClientProvider.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/NettyRemotingClientTest.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/UptimeClientHandler.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/simple
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/simple/SimpleClientProvider.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingClientListener.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/ClientIdentificationMessage.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/FutureAction.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MessagePropertyDecoder.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MessagePropertyEncoder.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MozzesObjectDecoder.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MozzesObjectEncoder.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/Unique.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/ClientGroup.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/ClientIdentity.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/IdentificationHandler.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/MozzesServerHandler.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/MozzesServerPipelineFactory.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/NettyRemotingServer.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/NettyServerConfiguration.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/OneResponse.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/ServerListener.java
Modified:
/trunk/mozzesApplication/mozzesApplicationDemo/pom.xml
/trunk/mozzesApplication/mozzesApplicationDemo/src/test/java/org/mozzes/application/demo/apps/TestBase.java
/trunk/mozzesApplication/mozzesApplicationDemo/src/test/java/org/mozzes/application/demo/apps/TestClientLogin.java
/trunk/mozzesApplication/mozzesApplicationExample/mozzesApplicationExampleSwingClient/src/main/java/org/mozzes/application/example/swing/ApplicationContext.java
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingClient/src/main/java/org/mozzes/application/remoting/client/RemoteClientConfiguration.java
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingPlugin.java
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingServerListener.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingClient.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingClientFactory.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingExecutorProviderFactory.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/core/RemotingClientImpl.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/ondemand/RemotingOnDemandClientProvider.java
/trunk/mozzesRemoting/mozzesRemotingClient/src/test/java/org/mozzes/remoting/client/pool/RemotingExecutorPoolManagerConfigurationTest.java
/trunk/mozzesRemoting/mozzesRemotingCommon/pom.xml
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingAction.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingConfiguration.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingException.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingProtocol.java
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingResponse.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/RemotingActionDispatcher.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/RemotingActionMapping.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/RemotingClientInfo.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/RemotingClientListener.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/RemotingClientManager.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/RemotingServer.java
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/RemotingServerFactory.java
=======================================
--- /dev/null
+++
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingClient/src/main/java/org/mozzes/application/remoting/client/NettyRemoteClientConfiguration.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,30 @@
+package org.mozzes.application.remoting.client;
+
+import org.mozzes.application.common.client.MozzesClientConfiguration;
+import org.mozzes.application.common.session.SessionIdProvider;
+import org.mozzes.invocation.common.handler.InvocationHandler;
+import org.mozzes.remoting.client.netty.NettyRemotingClient;
+import org.mozzes.remoting.client.netty.NettyRemotingClientProvider;
+
+import org.mozzes.remoting.common.RemotingActionExecutorProvider;
+import org.mozzes.remoting.common.RemotingConfiguration;
+import org.mozzes.remoting.common.RemotingException;
+
+public class NettyRemoteClientConfiguration extends
MozzesClientConfiguration {
+
+ private RemotingActionExecutorProvider clientProvider;
+
+ public NettyRemoteClientConfiguration(RemotingConfiguration
remotingConfiguration, Integer clientId) throws RemotingException {
+ this.clientProvider = new NettyRemotingClientProvider(new
NettyRemotingClient(remotingConfiguration));
+ }
+
+ public NettyRemoteClientConfiguration(RemotingActionExecutorProvider
clientProvider) {
+ this.clientProvider = clientProvider;
+ }
+
+ @Override
+ protected <I> InvocationHandler<I> getInvocationHandler(Class<I>
invocationInterface, SessionIdProvider sessionIDProvider) {
+ return new RemoteInvocationHandler<I>(clientProvider, sessionIDProvider);
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/NettyRemotingPlugin.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,59 @@
+package org.mozzes.application.remoting.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.mozzes.application.module.ServerLifecycleListener;
+import org.mozzes.application.plugin.ApplicationPlugin;
+import org.mozzes.remoting.server.netty.NettyServerConfiguration;
+
+import com.google.inject.Binder;
+
+/**
+ * Netty remoting plugin.
+ *
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ * @author Vladimir Todorovic
+ */
+public class NettyRemotingPlugin extends ApplicationPlugin {
+
+ /** Port on which server accepts connections. */
+ private final NettyServerConfiguration nettyServerConfiguration;
+
+ /**
+ * Creates plugin for Netty remoting server.
+ *
+ * @throws IllegalArgumentException if server configuration is null
and/or server listener is null
+ */
+ public NettyRemotingPlugin(NettyServerConfiguration
nettyServerConfiguration) throws IllegalArgumentException {
+
+ if (nettyServerConfiguration == null) {
+ throw new IllegalArgumentException("Netty server configuration can not
be null");
+ }
+
+ this.nettyServerConfiguration = nettyServerConfiguration;
+ }
+
+ /*
+ * Here we provide the binding that is needed to accept remote service
calls
+ *
+ * @see ApplicationModule#doCustomBinding(Binder)
+ */
+ @Override
+ public void doCustomBinding(Binder binder) {
+
binder.bind(NettyServerConfiguration.class).toInstance(nettyServerConfiguration);
+ }
+
+ /*
+ * Create new listener for the remote actions(that contains remove
service invocations)
+ *
+ * @see ApplicationModule#getServerListeners()
+ */
+ @Override
+ public List<Class<? extends ServerLifecycleListener>>
getServerListeners() {
+ List<Class<? extends ServerLifecycleListener>> returnValue = new
ArrayList<Class<? extends ServerLifecycleListener>>();
+ returnValue.add(NettyRemotingServerListener.class);
+ return returnValue;
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/NettyRemotingServerListener.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,52 @@
+package org.mozzes.application.remoting.server;
+
+import java.io.IOException;
+
+import org.mozzes.application.module.ServerInitializationException;
+import org.mozzes.application.module.ServerLifecycleListener;
+import org.mozzes.remoting.server.RemotingServer;
+import org.mozzes.remoting.server.RemotingServerFactory;
+import org.mozzes.remoting.server.netty.NettyServerConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+/**
+ * Listener which interact based upon received event. It starts or shuts
down netty server.
+ *
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ * @author Vladimir Todorovic
+ */
+public class NettyRemotingServerListener implements
ServerLifecycleListener {
+
+ private static final Logger logger =
LoggerFactory.getLogger(NettyRemotingServerListener.class);
+
+ @Inject
+ private NettyServerConfiguration nettyServerConfiguration;
+
+ @Inject
+ private Injector injector;
+
+ @Override
+ public void startup() throws ServerInitializationException {
+ InvocationActionMapping mappings =
injector.getInstance(InvocationActionMapping.class);
+
+ RemotingServer nettyRemotingServer =
RemotingServerFactory.getNettyServer(nettyServerConfiguration);
+ nettyRemotingServer.addActionMapping(mappings);
+
+ try {
+ nettyRemotingServer.startServer();
+ } catch (IOException e) {
+ throw new ServerInitializationException("Unable to start Netty remoting
server", e);
+ }
+ }
+
+ @Override
+ public void shutdown() {
+
RemotingServerFactory.getNettyServer(nettyServerConfiguration).stopServer();
+
logger.info("Netty remoting server stopped");
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingExecutorsPlugin.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,23 @@
+package org.mozzes.application.remoting.server;
+
+import org.mozzes.application.plugin.ApplicationPlugin;
+
+import com.google.inject.Binder;
+import com.google.inject.Scopes;
+
+/**
+ * Binds invocations needed for client remoting calls. Clients need them
to invoke their requests/actions on the server side.
+ *
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ *
+ */
+public class RemotingExecutorsPlugin extends ApplicationPlugin {
+
+ @Override
+ public void doCustomBinding(Binder binder) {
+ super.doCustomBinding(binder);
+ binder.bind(InvocationActionExecutor.class).in(Scopes.SINGLETON);
+ binder.bind(InvocationActionMapping.class).in(Scopes.SINGLETON);
+ binder.bind(InvocationExecutorProvider.class).in(Scopes.SINGLETON);
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/MozzesClientHandler.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,90 @@
+package org.mozzes.remoting.client.netty;
+
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.netty.channel.ChannelEvent;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.mozzes.remoting.common.netty.FutureAction;
+import org.mozzes.remoting.common.netty.Unique;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Handle incoming messages from the server. Also, it keeps a list of
client's requests in order to successfully
+ * return response to requested client action. In case of lost
communication channel with server, all client's requests
+ * are notified about this event so they can stop waiting to an
answer/response from the server.
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ *
+ */
+public class MozzesClientHandler extends SimpleChannelUpstreamHandler {
+
+ private static final Logger logger =
LoggerFactory.getLogger(MozzesClientHandler.class);
+
+ private final ConcurrentHashMap<Long, FutureAction>
synchronizedRequestsAndResponses;
+
+ /**
+ * Creates Mozzes client handler. It is responsible for receiving
messages/responses from the server and redirecting
+ * those to a proper request. (One response correspond to one request)
+ * @param synchronizedRequestsAndResponses holds client requests
identified by its ID.
+ */
+ public MozzesClientHandler(ConcurrentHashMap<Long, FutureAction>
synchronizedRequestsAndResponses) {
+ this.synchronizedRequestsAndResponses = synchronizedRequestsAndResponses;
+ }
+
+ @Override
+ public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
throws Exception {
+
+ if (e instanceof ChannelStateEvent) {
+ logger.debug("[handle upstream] " + e.toString());
+ }
+
+ super.handleUpstream(ctx, e);
+ }
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
+
+ Object message = e.getMessage();
+ if (message instanceof Unique) {
+ long uniqueId = ((Unique)message).getId();
+ synchronizedRequestsAndResponses.remove(uniqueId).setResponse(message);
+ } else {
+ logger.error("Message received which unknown id. Unexpected messge.");
+ throw new Exception("Message received whith unknown id. Unexpected
message.");
+ }
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
+ logger.error("Unexpected exception from downstream.", e.getCause());
+ e.getChannel().close();
+ }
+
+ @Override
+ public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
+ sendErrorMessagesForWaitingResponses();
+ super.channelClosed(ctx, e);
+ }
+
+ /**
+ * Send general error message to client's requests who wait for their
responses. This is a case when there are clients
+ * who haven't yet got their response and when communication with server
is lost they have to be notified so they don't
+ * wait anymore.
+ */
+ private void sendErrorMessagesForWaitingResponses() {
+ for (FutureAction response: synchronizedRequestsAndResponses.values()) {
+ response.setResponse(new Exception("channel closed."));
+ }
+
+ synchronizedRequestsAndResponses.clear();
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/MozzesClientPipelineFactory.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,89 @@
+package org.mozzes.remoting.client.netty;
+
+import static org.jboss.netty.channel.Channels.pipeline;
+
+import org.jboss.netty.channel.ChannelHandler;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.handler.codec.compression.ZlibDecoder;
+import org.jboss.netty.handler.codec.compression.ZlibEncoder;
+import org.jboss.netty.handler.codec.compression.ZlibWrapper;
+import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
+import org.jboss.netty.handler.codec.frame.LengthFieldPrepender;
+import org.jboss.netty.handler.codec.serialization.ClassResolvers;
+import org.jboss.netty.handler.codec.serialization.ObjectDecoder;
+import org.jboss.netty.handler.codec.serialization.ObjectEncoder;
+import org.jboss.netty.handler.logging.LoggingHandler;
+import org.mozzes.remoting.common.netty.MessagePropertyEncoder;
+import org.mozzes.remoting.common.netty.MozzesObjectDecoder;
+import org.mozzes.remoting.common.netty.MozzesObjectEncoder;
+
+
+/**
+ * Pipelines connected in a sequence in meaningful way, so it
+ * can handle client interaction to the server.
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ * @author Vladimir Todorovic
+ */
+public class MozzesClientPipelineFactory implements ChannelPipelineFactory
{
+
+ private final ChannelHandler businessHandler;
+ private final boolean newServer;
+
+ /**
+ * Creates client pipeline factory.
+ *
+ * @param businessHandler - this is our business handler
+ * @param newServer - if it's <code>false</code> it is going to be
created the sequence of pipelines which can handle
+ * old mozzes remoting protocol. Otherwise, the sequence of pipelines is
going to be created so clients communicate
+ * through new netty remoting protocol.
+ */
+ public MozzesClientPipelineFactory(ChannelHandler businessHandler,
boolean newServer) {
+ this.businessHandler = businessHandler;
+ this.newServer = newServer;
+ }
+
+ @Override
+ public ChannelPipeline getPipeline() throws Exception {
+ ChannelPipeline pipeline = pipeline();
+
+ if(newServer) {
+ createNewPipeline(pipeline);
+ }else {
+ createOldPipeline(pipeline);
+ }
+
+ // and then business logic.
+ pipeline.addLast("handler", businessHandler);
+ return pipeline;
+ }
+
+ /**
+ * Create new style remoting protocol where netty (Java NIO) is used as
remoting protocol. Other pipelines
+ * here ensures that requests and responses are handled well.
+ * @param pipeline pipeline onto which others are attached
+ */
+ private void createNewPipeline(ChannelPipeline pipeline) {
+ pipeline.addLast("deflater", new ZlibEncoder(ZlibWrapper.GZIP));
+ pipeline.addLast("inflater", new ZlibDecoder(ZlibWrapper.GZIP));
+ pipeline.addLast("logger", new LoggingHandler()); //DOWNSTREAM/UPSTREAM
logging
+ pipeline.addLast("encoder", new ObjectEncoder(1024));//DOWNSTREAM
+ pipeline.addLast("decoder", new ObjectDecoder(5242880,
ClassResolvers.weakCachingResolver(null)));//UPSTREAM
+ }
+
+ /**
+ * Creates old style remoting protocol where mozzes itself on low level
handled
+ * requests and responses using Java IO technique.
+ * @param pipeline pipeline onto which others are attached
+ */
+ private void createOldPipeline(ChannelPipeline pipeline) {
+ pipeline.addLast("logger", new LoggingHandler());
//DOWNSTREAM/UPSTREAM logging
+ pipeline.addLast("messagePropsEncode", new MessagePropertyEncoder());
//DOWNSTREAM da li se koristi kompresija i kriptovanje
+ pipeline.addLast("messageSize", new LengthFieldPrepender(4));
//DOWNSTREAM duzina poruke
+ pipeline.addLast("messageSizeStrip", new
LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4));//UPSTREAM odseca iz
poruke informaciju o duzini poruke
+ pipeline.addLast("decoder", new MozzesObjectDecoder(1048576, 0, 4, 0,
0)); //UPSTREAM deserijalizuje objekat
+ pipeline.addLast("encoder", new MozzesObjectEncoder());
//DOWNSTREAM serijalizuje objekat
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/NettyRemotingClient.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,162 @@
+package org.mozzes.remoting.client.netty;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
+import org.mozzes.remoting.client.RemotingClient;
+
+import org.mozzes.remoting.common.RemotingAction;
+import org.mozzes.remoting.common.RemotingClientListener;
+import org.mozzes.remoting.common.RemotingConfiguration;
+import org.mozzes.remoting.common.RemotingException;
+import org.mozzes.remoting.common.RemotingResponse;
+import org.mozzes.remoting.common.netty.ClientIdentificationMessage;
+import org.mozzes.remoting.common.netty.FutureAction;
+
+/**
+ * Remoting client which sits on Netty NIO client. Using Netty mechanism
client dispatch remote actions to the server for
+ * execution. Simple spoken, a client is responsible for connecting,
disconnecting and executing remote actions.
+ *
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ * @author Vladimir Todorovic
+ */
+public class NettyRemotingClient extends RemotingClientListener implements
RemotingClient {
+
+ private static final boolean NEW_SERVER = true;
+ private ClientBootstrap bootstrap;
+ private Channel channel;
+
+ /**
+ * Unique id for each remoting action.
+ */
+ private AtomicLong uniqeId = new AtomicLong();
+
+ /**
+ * Service to dispatch client remote actions to the server. It has
<strong>>one</strong>
+ * worker so it ensures it can not happen simultaneous write on a single
communication channel.
+ */
+ private ExecutorService service = Executors.newFixedThreadPool(1);
+
+ /**
+ * It allows that one client can send more remote actions on execution,
so it doesn't have to wait
+ * on a single action response. This is a map which keeps track which
action correspond to which respond.
+ */
+ private ConcurrentHashMap<Long, FutureAction>
synchronizedRequestsAndResponses = new ConcurrentHashMap<Long,
FutureAction>();
+
+ /**
+ * Create Netty remoting client based on this configuration.
+ *
+ * @param configuration - remoting configuration used to create stuff for
the client. Also, it has parameters for
+ * the connection.
+ */
+ public NettyRemotingClient(RemotingConfiguration configuration) {
+ // Configure the client.
+ bootstrap = new ClientBootstrap(new
NioClientSocketChannelFactory(Executors.newCachedThreadPool(),
+ Executors.newCachedThreadPool()));
+
+ MozzesClientHandler handler = new
MozzesClientHandler(synchronizedRequestsAndResponses);
+ bootstrap.setOption("remoteAddress", new
InetSocketAddress(configuration.getHost(), configuration.getPort()));
+ bootstrap.setPipelineFactory(new MozzesClientPipelineFactory(handler,
NEW_SERVER));
+
+ bootstrap.setOption("tcpNoDelay", true);
+ bootstrap.setOption("keepAlive", true);
+ }
+
+ @Override
+ public synchronized RemotingResponse execute(RemotingAction action)
throws RemotingException {
+ //this is blocking sync execution
+ Object serverResponse;
+ try {
+ serverResponse = executeAsync(action).get();
+ } catch (Exception exception) {
+ throw new RemotingException(exception);
+ }
+
+ if (serverResponse instanceof RemotingResponse) {
+ return (RemotingResponse) serverResponse;
+ } else if (serverResponse instanceof RemotingException) {
+ throw (RemotingException) serverResponse;
+ } else {
+ throw new RemotingException("Unknown reply from remoting server! (" +
serverResponse + ")");
+ }
+ }
+
+ /**
+ * Asynchronous execution of the action.
+ * @param action action to be executed remotely
+ * @return {@link Future} is returned holding future result.
+ * @throws RemotingException error while executing action.
+ */
+ private Future<Object> executeAsync(RemotingAction action) throws
RemotingException {
+ if (!channel.isConnected()) {
+ throw new RemotingException("Communication channel is unreacheable! Can
not send execution request.");
+ }
+
+ action.setId(getNextUniqueId());
+
+ FutureAction responceAsync = new FutureAction(channel, action);
+ synchronizedRequestsAndResponses.put(action.getId(), responceAsync);
+ return service.submit(responceAsync);
+ }
+
+ /**
+ * Generate next unique id.
+ * @return next unique id
+ */
+ private Long getNextUniqueId() {
+ return uniqeId.incrementAndGet();
+ }
+
+
+ @Override
+ public void connect() throws RemotingException {
+ // Start the connection attempt.
+ ChannelFuture channelFuture = bootstrap.connect();
+ channel = channelFuture.awaitUninterruptibly().getChannel();
+
+ if (!channel.isConnected()) {
+ disconnect();
+ throw new RemotingException("not connected yet.");
+ }
+ }
+
+ @Override
+ public void disconnect() {
+ // Close the connection. Make sure the close operation ends because
+ // all I/O operations are asynchronous in Netty.
+ channel.close().awaitUninterruptibly();
+
+ // Shut down all thread pools to exit.
+ bootstrap.releaseExternalResources();
+ }
+
+ @Override
+ public boolean isConnected() {
+ return channel == null ? false : channel.isConnected();
+ }
+
+ @Override
+ public void clientIsConnected(Integer clientId) {
+ channel.write(new
ClientIdentificationMessage(clientId)).awaitUninterruptibly();
+ }
+
+ @Override
+ public void loginClientFailed() {
+ disconnect();
+ }
+
+ @Override
+ public void clientLogout() {
+ disconnect();
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/NettyRemotingClientProvider.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,35 @@
+package org.mozzes.remoting.client.netty;
+
+import org.mozzes.remoting.client.RemotingClient;
+
+import org.mozzes.remoting.common.RemotingActionExecutor;
+import org.mozzes.remoting.common.RemotingActionExecutorProvider;
+import org.mozzes.remoting.common.RemotingException;
+
+/**
+ * Simple client provider that holds only one client and connects it at
the startup. Ideal for uses where only one
+ * client is needed and we don't want a pool.
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ * @author Vladimir Todorovic
+ */
+public class NettyRemotingClientProvider implements
RemotingActionExecutorProvider {
+
+ private final RemotingClient client;
+
+ /**
+ * Creates provader for Netty clients.
+ *
+ * @throws RemotingException if remoting server is not available or any
network problem while trying to establish connection
+ */
+ public NettyRemotingClientProvider(NettyRemotingClient
nettyRemotingClient) throws RemotingException {
+ this.client = nettyRemotingClient;
+ this.client.connect();
+ }
+
+ @Override
+ public RemotingActionExecutor get() {
+ return client;
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/NettyRemotingClientTest.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,15 @@
+package org.mozzes.remoting.client.netty;
+
+import org.mozzes.remoting.common.RemotingConfiguration;
+
+public class NettyRemotingClientTest {
+
+ public static void main(String[] args) throws Exception {
+ NettyRemotingClient client = new NettyRemotingClient(new
RemotingConfiguration("127.0.0.1", 5321));
+ client.connect();
+ System.out.println(client.isConnected());
+ client.disconnect();
+
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/netty/UptimeClientHandler.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,102 @@
+package org.mozzes.remoting.client.netty;
+
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.jboss.netty.util.Timeout;
+import org.jboss.netty.util.Timer;
+import org.jboss.netty.util.TimerTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * Tries to keep client connected all the time<br>
+ * Reconnect occurs every 5 seconds
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ */
+public class UptimeClientHandler extends SimpleChannelUpstreamHandler {
+
+ private Logger logger =
LoggerFactory.getLogger(UptimeClientHandler.class);
+
+ private final ClientBootstrap bootstrap;
+ private final Timer timer;
+ private long startTime = -1;
+
+ // Sleep 5 seconds before a reconnection attempt.
+ static final int RECONNECT_DELAY = 5;
+
+ /**
+ * Set up handler that tries to reconnect client in time manner specified
by timer.
+ * Reconnection occurs only if client is disconnected, obviously.
+ * @param bootstrap client bootstrap configuration.
+ * @param timer timer used to control reconnection.
+ */
+ public UptimeClientHandler(ClientBootstrap bootstrap, Timer timer) {
+ this.bootstrap = bootstrap;
+ this.timer = timer;
+ }
+
+ InetSocketAddress getRemoteAddress() {
+ return (InetSocketAddress) bootstrap.getOption("remoteAddress");
+ }
+
+ @Override
+ public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
+ println("Sleeping for: " + RECONNECT_DELAY + "s");
+ timer.newTimeout(new TimerTask() {
+ @Override
+ public void run(Timeout timeout) throws Exception {
+ println("Reconnecting to: " + getRemoteAddress());
+ bootstrap.connect();
+ }
+ }, RECONNECT_DELAY, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent
e) throws Exception {
+ if (startTime < 0) {
+ startTime = System.currentTimeMillis();
+ }
+ println("Connected to: " + getRemoteAddress());
+ }
+
+ @Override
+ public void channelDisconnected(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
+ println("Disconnected from: " + getRemoteAddress());
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
+ Throwable cause = e.getCause();
+ if (cause instanceof ConnectException) {
+ startTime = -1;
+ println("Failed to connect: " + cause.getMessage());
+ }
+ ctx.getChannel().close();
+ }
+
+ void println(String msg) {
+ if (startTime < 0) {
+ logger.error("[SERVER IS DOWN] {}", msg);
+ } else {
+ logger.debug("[UPTIME: {}] \n{}", (System.currentTimeMillis() -
startTime) / 1000, msg);
+ }
+ }
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
+ println(e.getMessage().toString());
+ super.messageReceived(ctx, e);
+ }
+
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/simple/SimpleClientProvider.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2010 Mozzart
+ *
+ *
+ * This file is part of mozzes.
+ *
+ * mozzes 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * mozzes 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 mozzes. If not, see <
http://www.gnu.org/licenses/>.
+ *
+ */
+package org.mozzes.remoting.client.simple;
+
+import org.mozzes.remoting.client.RemotingClient;
+import org.mozzes.remoting.client.RemotingClientFactory;
+import org.mozzes.remoting.common.RemotingActionExecutor;
+import org.mozzes.remoting.common.RemotingActionExecutorProvider;
+import org.mozzes.remoting.common.RemotingConfiguration;
+import org.mozzes.remoting.common.RemotingException;
+
+/**
+ * Simple client provider that holds only one client and connects it at
the startup. Ideal for uses where only one
+ * client is needed and we don't want a pool.
+ *
+ * @author Kokan
+ */
+public class SimpleClientProvider implements
RemotingActionExecutorProvider {
+
+ private final RemotingClient client;
+
+ /**
+ * Default constructor
+ *
+ * @param remotingConfiguration Configuration for which client provider
is created
+ * @param clientFactory Factory for creating clients
+ * @throws RemotingException If remoting server is not available or any
network problem while trying to
+ * establish connection
+ */
+ public SimpleClientProvider(RemotingConfiguration remotingConfiguration,
+ RemotingClientFactory clientFactory) throws RemotingException {
+ this.client = clientFactory.create(remotingConfiguration);
+ this.client.connect();
+ }
+
+ @Override
+ public RemotingActionExecutor get() {
+ return client;
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingClientListener.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,26 @@
+package org.mozzes.remoting.common;
+
+/**
+ * Listener for remoting client.
+ *
+ * @author Vladimir Todorovic
+ */
+public abstract class RemotingClientListener {
+
+ /**
+ * Executed when client is connected.
+ *
+ * @param clientId - client's ID
+ */
+ public abstract void clientIsConnected(Integer clientId);
+
+ /**
+ * Executed when failed to login on remoting server.
+ */
+ public abstract void loginClientFailed();
+
+ /**
+ * Executed when client execute logout.
+ */
+ public abstract void clientLogout();
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/ClientIdentificationMessage.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,38 @@
+package org.mozzes.remoting.common.netty;
+
+import java.io.Serializable;
+
+/**
+ * Client uses this message for identification on remoting server.
+ *
+ * @author Vladimir Todorovic
+ */
+public final class ClientIdentificationMessage implements Serializable {
+
+ private static final long serialVersionUID = -8446761234541725707L;
+
+ private final Integer clientId;
+
+ /**
+ * Creates identification message.
+ *
+ * @param clientId - ID of the client
+ * @throws IllegalArgumentException if client ID is null
+ */
+ public ClientIdentificationMessage(Integer clientId) throws
IllegalArgumentException {
+ if (clientId == null) {
+ throw new IllegalArgumentException("Client ID can not be null.");
+ }
+
+ this.clientId = clientId;
+ }
+
+ /**
+ * Returns client ID.
+ *
+ * @return ID of the client
+ */
+ public Integer getClientId() {
+ return this.clientId;
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/FutureAction.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,81 @@
+package org.mozzes.remoting.common.netty;
+
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelFutureListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.mozzes.remoting.common.RemotingAction;
+
+/**
+ * Sends action on execution. It blocks itself until someone call {@link
#setResponse(Object)} method.
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ *
+ */
+public class FutureAction implements Callable<Object> {
+
+ private static final Logger logger =
LoggerFactory.getLogger(FutureAction.class);
+
+ private Channel communicationChannel;
+ private RemotingAction remotingAction;
+
+ /**
+ * Ensure that action will get its response.
+ */
+ private CountDownLatch lock = new CountDownLatch(1);
+
+ private Object response;
+
+ /**
+ * Creates future action. This action is as soon as possible submitted
for execution.
+ * After submitting special worker thread will hold on for receiving
response.
+ * @param communicationChannel channel through which we send action
+ * @param remotingAction action to be sent on execution.
+ */
+ public FutureAction(Channel communicationChannel, RemotingAction
remotingAction) {
+ this.communicationChannel = communicationChannel;
+ this.remotingAction = remotingAction;
+ }
+
+ @Override
+ public Object call() throws Exception {
+
+ final long remotingCallStarted = System.currentTimeMillis();
+ ChannelFuture future = communicationChannel.write(remotingAction);
+ future.addListener(new ChannelFutureListener() {
+
+ @Override
+ public void operationComplete(ChannelFuture future) throws Exception {
+ long remotingCallEnded = System.currentTimeMillis();
+ long callDuration = remotingCallEnded - remotingCallStarted;
+
+ logger.debug("remoting call for {} took {}ms",
remotingAction.getActionName(), callDuration);
+ }
+ });
+
+ //waits for the response.
+ lock.await();
+
+ return response;
+ }
+
+ /**
+ * Set the response received from the server. After receiving this
response client who waited for it
+ * is waken.
+ * @param response represent response from the server.
+ */
+ public void setResponse(Object response) {
+
+ this.response = response;
+
+ //user has got his response - let him know that.
+ lock.countDown();
+ }
+
+}
+
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MessagePropertyDecoder.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,40 @@
+package org.mozzes.remoting.common.netty;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
+
+/**
+ * This one decode message and it is used when dealing with old remoting
protocol.
+ * Netty support the old one protocol.
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ *
+ */
+public class MessagePropertyDecoder extends OneToOneDecoder {
+ private AtomicBoolean received = new AtomicBoolean(false);
+
+ @Override
+ protected Object decode(ChannelHandlerContext ctx, Channel channel,
Object msg) throws Exception {
+ if (received.get()) {
+ return msg;
+ }
+ try {
+ if (!(msg instanceof ChannelBuffer)) {
+ return msg;
+ }
+ ChannelBuffer body = (ChannelBuffer) msg;
+ body.readByte();
+ body.readByte();
+
+ return body;
+ } finally {
+ received.set(true);
+ }
+
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MessagePropertyEncoder.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,46 @@
+package org.mozzes.remoting.common.netty;
+
+import static org.jboss.netty.buffer.ChannelBuffers.*;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
+
+/**
+ * MozzesRemoting protokol zahteva u PRVOJ poruci informaciju o tome da li
je poruka kompresovana ili enkriptovana.<br>
+ * Ovaj encoder oba propertija za sada stavlja na false :)
+ *
+ * @author bojanb
+ *
+ */
+public class MessagePropertyEncoder extends OneToOneEncoder {
+
+ /**
+ * Da li je neka poruka vec poslata
+ */
+ private AtomicBoolean sent = new AtomicBoolean(false);
+
+ @Override
+ protected Object encode(ChannelHandlerContext ctx, Channel channel,
Object msg) throws Exception {
+ if (sent.get()) {
+ return msg;
+ }
+ try {
+ if (!(msg instanceof ChannelBuffer)) {
+ return msg;
+ }
+ ChannelBuffer body = (ChannelBuffer) msg;
+ ChannelBuffer header =
channel.getConfig().getBufferFactory().getBuffer(body.order(), 2);
+ header.writeShort(0);
+
+ return wrappedBuffer(header, body);
+ } finally {
+ sent.set(true);
+ }
+
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MozzesObjectDecoder.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,33 @@
+package org.mozzes.remoting.common.netty;
+
+import java.io.ObjectInputStream;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBufferInputStream;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
+
+/**
+ * @author bojanb
+ * Pravi Java objekat od niza bajtova
+ */
+public class MozzesObjectDecoder extends LengthFieldBasedFrameDecoder {
+
+
+
+ public MozzesObjectDecoder(int maxFrameLength, int lengthFieldOffset, int
lengthFieldLength, int lengthAdjustment,
+ int initialBytesToStrip) {
+ super(maxFrameLength, lengthFieldOffset, lengthFieldLength,
lengthAdjustment, initialBytesToStrip);
+ }
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, ChannelBuffer
buffer) throws Exception {
+ return new ObjectInputStream(
+ new ChannelBufferInputStream(buffer)).readObject();
+ }
+
+
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/MozzesObjectEncoder.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,42 @@
+package org.mozzes.remoting.common.netty;
+
+import static org.jboss.netty.buffer.ChannelBuffers.dynamicBuffer;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.jboss.netty.buffer.ChannelBufferOutputStream;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
+
+/**
+ * @author bojanb
+ * Serijalizuje objekat
+ */
+public class MozzesObjectEncoder extends OneToOneEncoder {
+
+ @Override
+ protected Object encode(ChannelHandlerContext ctx, Channel channel,
Object msg) throws Exception {
+ ObjectOutputStream objectOutputStream = null;
+
+ try {
+ ChannelBufferOutputStream bout = new ChannelBufferOutputStream(
+ dynamicBuffer(1024, ctx.getChannel().getConfig().getBufferFactory()));
+
+ objectOutputStream = new ObjectOutputStream(bout);
+ objectOutputStream.writeObject(msg);
+ objectOutputStream.flush();
+
+ return bout.buffer();
+ } finally {
+ if (objectOutputStream != null) {
+ try {
+ objectOutputStream.close();
+ } catch (IOException ioe) {
+ }
+ }
+ }
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/netty/Unique.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,21 @@
+package org.mozzes.remoting.common.netty;
+
+/**
+ * Ensure that object that implement this interface has a unique state.
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ *
+ */
+public interface Unique {
+
+ /**
+ * Set unique id of some object.
+ * @param id unique id of some object
+ */
+ public void setId(Long id);
+
+ /**
+ * Get unique id of some object.
+ * @return unique id of some object
+ */
+ public Long getId();
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/ClientGroup.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,44 @@
+package org.mozzes.remoting.server.netty;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Thread-safe set that contains client IDs. This set cannot contain two
identical IDs.
+ *
+ * @author Vladimir Todorovic
+ */
+final class ClientGroup {
+
+ private final Set<Integer> clients;
+
+ ClientGroup() {
+ clients = new HashSet<Integer>();
+ }
+
+ /**
+ * Adds the client ID to this set if client ID is not already present.
+ *
+ * @param clientId - client ID
+ * @return {@code true} if this set did not already contain the client
ID, {@code false} otherwise
+ * @throws IllegalArgumentException if client ID is null
+ */
+ synchronized boolean addIfAbsent(Integer clientId) throws
IllegalArgumentException {
+ if (clientId == null) {
+ throw new IllegalArgumentException("Client ID cannot be null.");
+ }
+
+ return clients.add(clientId);
+ }
+
+ /**
+ * Removes client ID from this set.
+ *
+ * @param clientId - client ID
+ */
+ synchronized void remove(Integer clientId) {
+ if (clientId != null) {
+ clients.remove(clientId);
+ }
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/ClientIdentity.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,39 @@
+package org.mozzes.remoting.server.netty;
+
+/**
+ * Client's identity.
+ *
+ * @author Vladimir Todorovic
+ */
+public final class ClientIdentity {
+
+ private final int clientId;
+ private final boolean isAccepted;
+
+ /**
+ * Creates client's identity.
+ *
+ * @param clientId - client's ID
+ * @param isAccepted - {@code true} if identity accepted, {@code false}
otherwise
+ */
+ public ClientIdentity(int clientId, boolean isAccepted) {
+ this.clientId = clientId;
+ this.isAccepted = isAccepted;
+ }
+
+ /**
+ * @return client's ID
+ */
+ public int getClientId() {
+ return clientId;
+ }
+
+ /**
+ * @return {@code true} if identity accepted, {@code false} otherwise
+ */
+ public boolean isAccepted() {
+ return isAccepted;
+ }
+
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/IdentificationHandler.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,45 @@
+package org.mozzes.remoting.server.netty;
+
+import java.net.SocketAddress;
+
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.mozzes.remoting.common.netty.ClientIdentificationMessage;
+
+/**
+ * Handles identification for connected clients.
+ *
+ * @author Vladimir Todorovic
+ */
+public final class IdentificationHandler extends
SimpleChannelUpstreamHandler {
+
+ private static final Logger logger =
LoggerFactory.getLogger(IdentificationHandler.class);
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
+ if (e.getMessage() instanceof ClientIdentificationMessage) {
+ ClientIdentificationMessage identificationMessage =
(ClientIdentificationMessage) e.getMessage();
+
+ SocketAddress remoteAddress = ctx.getChannel().getRemoteAddress();
+ Integer clientId = identificationMessage.getClientId();
+
+ if (NettyRemotingServer.connectedClients.addIfAbsent(clientId)) {
+ ctx.getChannel().setAttachment(new ClientIdentity(clientId, true));
+
logger.info("Remote client is accepted [Remote address = " +
remoteAddress + ", Client ID = " + clientId + "]");
+ } else {
+ ctx.getChannel().setAttachment(new ClientIdentity(clientId, false));
+
logger.info("Remote client is not accepted [Remote address = " +
remoteAddress + ", Client ID = " + clientId + "]");
+ }
+
+ ctx.getPipeline().remove(this);
+
+ return;
+ }
+
+ super.messageReceived(ctx, e);
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/MozzesServerHandler.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,166 @@
+package org.mozzes.remoting.server.netty;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+
+import org.jboss.netty.channel.ChannelEvent;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.mozzes.remoting.server.RemotingActionDispatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.mozzes.remoting.common.RemotingAction;
+import org.mozzes.remoting.common.RemotingActionExecutor;
+import org.mozzes.remoting.common.RemotingException;
+import org.mozzes.remoting.common.RemotingResponse;
+
+/**
+ * This handler executes remoting actions on Mozzes server.
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ * @author Vladimir Todorovic
+ */
+public class MozzesServerHandler extends SimpleChannelUpstreamHandler {
+
+ private static final Logger logger =
LoggerFactory.getLogger(MozzesServerHandler.class);
+
+ private final RemotingActionDispatcher dispatcher;
+
+ /**
+ * Creates handler that executes remoting actions on Mozzes server.
+ *
+ * @param dispatcher - dispatches remoting action to the action executor
+ */
+ public MozzesServerHandler(RemotingActionDispatcher dispatcher) {
+ this.dispatcher = dispatcher;
+ }
+
+ @Override
+ public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
+ // HERE: Add all accepted channels to the group
+ // so that they are closed properly on shutdown
+ // If the added channel is closed before shutdown,
+ // it will be removed from the group automatically.
+ NettyRemotingServer.clientChannelGroup.add(ctx.getChannel());
+ super.channelOpen(ctx, e);
+ }
+
+ @Override
+ public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
throws Exception {
+ if (e instanceof ChannelStateEvent) {
+
logger.info(e.toString());
+ }
+ super.handleUpstream(ctx, e);
+ }
+
+ @Override
+ public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent
e) throws Exception {
+
logger.info("Client {} connected.",
InetAddress.getLocalHost().getHostName());
+ super.channelConnected(ctx, e);
+ }
+
+ @Override
+ public void channelDisconnected(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
+ // ako ih dodajemo onda ih i brisemo.
+ NettyRemotingServer.clientChannelGroup.remove(e.getChannel());
+ super.channelDisconnected(ctx, e);
+
+ Object channelAttachment = ctx.getChannel().getAttachment();
+
+ if (channelAttachment != null) {
+ ClientIdentity clientIdentity = (ClientIdentity) channelAttachment;
+
+ if (clientIdentity.isAccepted()) {
+
NettyRemotingServer.connectedClients.remove(clientIdentity.getClientId());
+ }
+ }
+ }
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent
messageEvent) {
+ long started = System.currentTimeMillis();
+
+ RemotingAction remoteAction = (RemotingAction) messageEvent.getMessage();
+ Long requestId = remoteAction.getId();
+
+ try {
+ Object channelAttachment = ctx.getChannel().getAttachment();
+
+ if (channelAttachment != null) {
+ ClientIdentity clientIdentity = (ClientIdentity) channelAttachment;
+
+ if (!clientIdentity.isAccepted()) {
+ logger.error("Client {} is already in use.",
clientIdentity.getClientId());
+ throw new RemotingException(new IllegalStateException(
+ "Client ID is already in use. Client ID: " +
clientIdentity.getClientId()));
+ }
+ }
+
+ RemotingResponse remotingResponse = execute(remoteAction);
+ remotingResponse.setId(requestId);
+
+ logger.debug("processAction() before sending result");
+ messageEvent.getChannel().write(remotingResponse);
+ logger.debug("processAction() after sending result");
+ } catch (ClassCastException ex) {
+ logger.error("Unknown class received from client", ex);
+
+ RemotingException exception = new RemotingException(ex);
+ exception.setId(requestId);
+ messageEvent.getChannel().write(exception);
+
+ logger.debug("processAction() after sending class cast exception");
+ } catch (RemotingException exception) {
+ // doslo je do greske prilikom izvrsavanja akcije
+ logger.debug("processAction() before sending remoting exception",
exception);
+ exception.setId(requestId);
+ messageEvent.getChannel().write(exception);
+ logger.debug("processAction() after sending remoting exception");
+ }
+
+ logger.debug("request processing took {} ms.",
(System.currentTimeMillis() - started));
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
+ logger.error("Unexpected exception from downstream.", e.getCause());
+
logger.info("exceptionCaught, num of clients in group is " +
NettyRemotingServer.clientChannelGroup.size());
+ }
+
+ /**
+ * Execute remote action logic.
+ *
+ * @param request request that came from client.
+ * @return action execution response.
+ * @throws RemotingException if action execution fails, exception is
thrown to indicate that error.
+ */
+ private RemotingResponse execute(RemotingAction request) throws
RemotingException {
+ logger.debug("Request received: {}", request);
+
+ RemotingActionExecutor actionExecutor =
dispatcher.getActionExecutor(request);
+
+ // izvrsavanje akcije
+ RemotingResponse response = null;
+ try {
+ logger.debug("processAction() before executing action");
+ response = actionExecutor.execute(request);
+ } catch (RemotingException ex) {
+ throw ex;
+ } catch (Throwable thr) {
+ throw new RemotingException(thr);
+ }
+
+ // akcija mora da vrati neki response klijentu
+ if (response == null) {
+ response = new RemotingResponse(new HashMap<Object, Object>());
+ }
+
+ return response;
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/MozzesServerPipelineFactory.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,64 @@
+package org.mozzes.remoting.server.netty;
+
+import static org.jboss.netty.channel.Channels.pipeline;
+
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.handler.codec.compression.ZlibDecoder;
+import org.jboss.netty.handler.codec.compression.ZlibEncoder;
+import org.jboss.netty.handler.codec.compression.ZlibWrapper;
+import org.jboss.netty.handler.codec.serialization.ClassResolvers;
+import org.jboss.netty.handler.codec.serialization.ObjectDecoder;
+import org.jboss.netty.handler.codec.serialization.ObjectEncoder;
+import org.jboss.netty.handler.execution.ExecutionHandler;
+import org.jboss.netty.handler.logging.LoggingHandler;
+import org.mozzes.remoting.server.RemotingActionDispatcher;
+
+/**
+ * Server pipeline factory used to create server business logic for
processing clients
+ * requests.
+ *
+ * @author Bojan Blagojevic <
bojan.bl...@mozzartbet.com>
+ * @author Vladimir Todorovic
+ */
+public class MozzesServerPipelineFactory implements ChannelPipelineFactory
{
+
+ private final RemotingActionDispatcher dispatcher;
+ private final ExecutionHandler executionHandler;
+
+ /**
+ * Creates server pipeline factory.
+ *
+ * @param dispatcher - dispatches remote actions to the action executors
+ * @param executionHandler - executes channel events without blocking I/O
worker threads
+ */
+ public MozzesServerPipelineFactory(RemotingActionDispatcher dispatcher,
ExecutionHandler executionHandler) {
+ this.dispatcher = dispatcher;
+ this.executionHandler = executionHandler;
+ }
+
+ @Override
+ public ChannelPipeline getPipeline() throws Exception {
+ ChannelPipeline pipeline = pipeline();
+ createNewPipeline(pipeline);
+
+ return pipeline;
+ }
+
+ /**
+ * On the given pipeline attach our pipes which creates
+ * Netty server logic. This logic process Netty clients requests.
+ *
+ * @param pipeline - pipeline to attach other logic
+ */
+ private void createNewPipeline(ChannelPipeline pipeline) {
+ pipeline.addLast("deflater", new ZlibEncoder(ZlibWrapper.GZIP));
+ pipeline.addLast("inflater", new ZlibDecoder(ZlibWrapper.GZIP));
+ pipeline.addLast("logger", new LoggingHandler());
+ pipeline.addLast("encoder", new ObjectEncoder(1024));
+ pipeline.addLast("decoder", new ObjectDecoder(5242880,
ClassResolvers.weakCachingConcurrentResolver(null)));
+ pipeline.addLast("identificationHandler", new IdentificationHandler());
+ pipeline.addLast("executor", executionHandler);
+ pipeline.addLast("handler", new MozzesServerHandler(dispatcher));
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/NettyRemotingServer.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,102 @@
+package org.mozzes.remoting.server.netty;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.group.ChannelGroup;
+import org.jboss.netty.channel.group.DefaultChannelGroup;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.jboss.netty.handler.execution.ExecutionHandler;
+import
org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
+import org.mozzes.remoting.server.RemotingServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This remoting server uses Netty for remoting.
+ */
+public class NettyRemotingServer extends RemotingServer {
+
+ private static final Logger logger =
LoggerFactory.getLogger(NettyRemotingServer.class);
+
+ /**
+ * All clients connected to the server are contained inhere. So, when
someone stop server,
+ * all these clients will be in once detached from the server.
+ */
+ static final ChannelGroup clientChannelGroup = new
DefaultChannelGroup("clients");
+
+ static final ClientGroup connectedClients = new ClientGroup();
+
+ // Configure the server.
+ private NioServerSocketChannelFactory channelFactory;
+ private ServerBootstrap bootstrap;
+ private ExecutionHandler executionHandler;
+
+ private final NettyServerConfiguration nettyServerConfiguration;
+
+ /**
+ *
+ * @param nettyServerConfiguration - configuration for Netty server
+ */
+ public NettyRemotingServer(NettyServerConfiguration
nettyServerConfiguration) {
+ super(nettyServerConfiguration.getNettyPort());
+
+ this.nettyServerConfiguration = nettyServerConfiguration;
+ }
+
+ @Override
+ public synchronized void startServer() {
+ if (bootstrap != null) {
+ return;
+ }
+
+ channelFactory = new
NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
+ Executors.newCachedThreadPool(),
+ nettyServerConfiguration.getIoworkers());
+
+ bootstrap = new ServerBootstrap(channelFactory);
+
+ executionHandler = new ExecutionHandler(new
OrderedMemoryAwareThreadPoolExecutor(nettyServerConfiguration.getWorkers(),
+ nettyServerConfiguration.getMemoryPerChannel(),
nettyServerConfiguration.getMemoryPerPool()));
+
+ ChannelPipelineFactory pipelineFactory = new
MozzesServerPipelineFactory(getDispatcher(), executionHandler);
+ bootstrap.setPipelineFactory(pipelineFactory);
+
+ bootstrap.setOption("child.tcpNoDelay", true);
+ bootstrap.setOption("child.keepAlive", true);
+
+ clientChannelGroup.add(bootstrap.bind(new InetSocketAddress(getPort())));
+
+
logger.info(nettyServerConfiguration.toString());
+ }
+
+ @Override
+ public synchronized void stopServer() {
+ if (bootstrap == null) {
+
logger.info("Server is already down.");
+ return;
+ }
+
+
logger.info("Shutting down server");
+ // HERE: Close all connections and server sockets.
+ clientChannelGroup.close().awaitUninterruptibly();
+
+ // HERE: Shutdown the selector loop (boss and worker).
+ channelFactory.releaseExternalResources();// <-- HERE
+ executionHandler.releaseExternalResources();
+
+ bootstrap = null;
+ }
+
+ @Override
+ public synchronized boolean isRunning() {
+ return bootstrap != null;
+ }
+
+ @Override
+ public synchronized int getNumberOfActiveClients() {
+ return clientChannelGroup.size();
+ }
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/NettyServerConfiguration.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,118 @@
+package org.mozzes.remoting.server.netty;
+
+/**
+ * Netty server configuration used for netty server.
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ *
+ */
+public class NettyServerConfiguration {
+
+ private Integer ioworkers;
+ private Integer workers;
+
+ private Integer memoryPerChannel;
+ private Integer memoryPerPool;
+
+ private Integer nettyPort;
+
+ /**
+ * Netty server configuration with default settings.
+ * Please note that server port is <code>null</code>
+ * meaning netty is disabled. Enable server by
+ * calling {@link #setNettyPort(Integer)} method.
+ */
+ public NettyServerConfiguration() {
+ ioworkers = 8;
+ workers = 40;
+ memoryPerPool = 52428800;
+ memoryPerChannel = 1048576;
+
+ nettyPort = null;
+ }
+
+ public Integer getIoworkers() {
+ return ioworkers;
+ }
+
+ public void setIoworkers(Integer ioworkers) {
+ if (ioworkers == null) {
+ return;
+ }
+ this.ioworkers = ioworkers;
+ }
+
+ public Integer getWorkers() {
+ return workers;
+ }
+
+ public void setWorkers(Integer workers) {
+ if (workers == null) {
+ return;
+ }
+
+ this.workers = workers;
+ }
+
+ public Integer getMemoryPerChannel() {
+ return memoryPerChannel;
+ }
+
+ public void setMemoryPerChannel(Integer memoryPerChannel) {
+ if (memoryPerChannel == null) {
+ return;
+ }
+
+ this.memoryPerChannel = memoryPerChannel;
+ }
+
+ public Integer getMemoryPerPool() {
+ return memoryPerPool;
+ }
+
+ public void setMemoryPerPool(Integer memoryPerPool) {
+ if (memoryPerPool == null) {
+ return;
+ }
+
+ this.memoryPerPool = memoryPerPool;
+ }
+
+ public Integer getNettyPort() {
+ return nettyPort;
+ }
+
+ public void setNettyPort(Integer nettyPort) {
+ this.nettyPort = nettyPort;
+ }
+
+ /**
+ * Netty is enabled if netty port is specified.
+ * @return <code>true</code> if netty is enabled, <code>false</code>
otherwise.
+ */
+ public boolean isNettyEnabled() {
+ return nettyPort != null;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("NettyServerConfiguration is ");
+ builder.append(isNettyEnabled() ? "ENABLED" : "DISABLED");
+ builder.append("\nParameters are:");
+ builder.append("\nioworkers=");
+ builder.append(ioworkers);
+ builder.append("\nworkers=");
+ builder.append(workers);
+ builder.append("\nmemoryPerChannel=");
+ builder.append(memoryPerChannel);
+ builder.append("\nmemoryPerPool=");
+ builder.append(memoryPerPool);
+ builder.append("\nnettyPort=");
+ builder.append(nettyPort);
+
+ return builder.toString();
+ }
+
+
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/OneResponse.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,43 @@
+package org.mozzes.remoting.server.netty;
+
+import java.util.concurrent.Callable;
+
+import org.jboss.netty.channel.Channel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represent one response.
+ * @author Marko Jovicic <
marko....@mozzartbet.com>
+ *
+ */
+public class OneResponse implements Callable<Void> {
+
+ private static final Logger logger =
LoggerFactory.getLogger(OneResponse.class);
+
+ private Channel channel;
+ private Object response;
+
+ /**
+ * Associate response with a channel.
+ * @param channel communication channel to the client.
+ * @param response response to send to the client.
+ */
+ public OneResponse(Channel channel, Object response) {
+ this.channel = channel;
+ this.response = response;
+ logger.debug("OneResponse object created and it is ready to be returned
to client.");
+ }
+
+ @Override
+ public Void call() throws Exception {
+
logger.info("writing response STARTED to the client.");
+ long started = System.currentTimeMillis();
+
+ channel.write(response).awaitUninterruptibly();
+
+ logger.debug("writing response took: " + (System.currentTimeMillis() -
started) + " ms");
+ return null;
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/mozzesRemoting/mozzesRemotingServer/src/main/java/org/mozzes/remoting/server/netty/ServerListener.java
Sat Dec 1 15:14:30 2012
@@ -0,0 +1,16 @@
+package org.mozzes.remoting.server.netty;
+
+/**
+ * Listener for Netty remoting server.
+ *
+ * @author Vladimir Todorovic
+ */
+public interface ServerListener {
+
+ /**
+ * Executed when client disconnected from Netty remoting server.
+ *
+ * @param clientId - ID of disconnected client
+ */
+ public void clientDisconnected(Integer clientId);
+}
=======================================
--- /trunk/mozzesApplication/mozzesApplicationDemo/pom.xml Tue Feb 23
16:09:19 2010
+++ /trunk/mozzesApplication/mozzesApplicationDemo/pom.xml Sat Dec 1
15:14:30 2012
@@ -9,7 +9,6 @@
<name>Mozzes Application Demo</name>
<description>demo apps using the mozzes application server and
client</description>
- <groupId>org.mozzes.application</groupId>
<artifactId>mozzesApplicationDemo</artifactId>
<dependencies>
=======================================
---
/trunk/mozzesApplication/mozzesApplicationDemo/src/test/java/org/mozzes/application/demo/apps/TestBase.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesApplication/mozzesApplicationDemo/src/test/java/org/mozzes/application/demo/apps/TestBase.java
Sat Dec 1 15:14:30 2012
@@ -62,6 +62,7 @@
import org.mozzes.application.remoting.server.RemotingPlugin;
import org.mozzes.application.server.MozzesServer;
import org.mozzes.application.server.MozzesServerConfiguration;
+import org.mozzes.remoting.common.RemotingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -206,7 +207,13 @@
if (isClientLocal())
return server.getLocalClient();
- return new MozzesClient(new RemoteClientConfiguration("localhost",
7890));
+ try {
+ return new MozzesClient(new RemoteClientConfiguration("localhost",
7890, true));
+ } catch (RemotingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
}
/**
=======================================
---
/trunk/mozzesApplication/mozzesApplicationDemo/src/test/java/org/mozzes/application/demo/apps/TestClientLogin.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesApplication/mozzesApplicationDemo/src/test/java/org/mozzes/application/demo/apps/TestClientLogin.java
Sat Dec 1 15:14:30 2012
@@ -30,6 +30,7 @@
import org.mozzes.application.common.exceptions.ClientLoggingException;
import org.mozzes.application.demo.mockups.MAuthorizationManager;
import org.mozzes.application.remoting.client.RemoteClientConfiguration;
+import org.mozzes.remoting.common.RemotingException;
/**
@@ -135,11 +136,14 @@
/* second client logging in with the same credentials */
try {
- MozzesClient client2 = new MozzesClient(new
RemoteClientConfiguration("localhost", 7890));
+ MozzesClient client2 = new MozzesClient(new
RemoteClientConfiguration("localhost", 7890, false));
client2.login(validUsername1, validPassword1);
client2.logout();
} catch (AuthorizationFailedException e) {
fail("should log in");
+ } catch (RemotingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
assert client != null;
=======================================
---
/trunk/mozzesApplication/mozzesApplicationExample/mozzesApplicationExampleSwingClient/src/main/java/org/mozzes/application/example/swing/ApplicationContext.java
Thu Mar 4 02:25:49 2010
+++
/trunk/mozzesApplication/mozzesApplicationExample/mozzesApplicationExampleSwingClient/src/main/java/org/mozzes/application/example/swing/ApplicationContext.java
Sat Dec 1 15:14:30 2012
@@ -27,6 +27,7 @@
import org.mozzes.application.common.client.MozzesClient;
import org.mozzes.application.example.common.ExampleConstants;
import org.mozzes.application.remoting.client.RemoteClientConfiguration;
+import org.mozzes.remoting.common.RemotingException;
public class ApplicationContext {
@@ -34,8 +35,8 @@
private final MozzesClient client;
- private ApplicationContext() {
- client = new MozzesClient(new
RemoteClientConfiguration(ExampleConstants.HOST, ExampleConstants.PORT));
+ private ApplicationContext() throws RemotingException {
+ client = new MozzesClient(new
RemoteClientConfiguration(ExampleConstants.HOST, ExampleConstants.PORT,
true));
}
private static ApplicationContext getInstance() {
@@ -46,6 +47,10 @@
JOptionPane.showMessageDialog(ExampleSwingClient.getApplicationMainFrame(),
"Server is not starated!");
System.exit(1);
+ } catch (RemotingException e) {
+
JOptionPane.showMessageDialog(ExampleSwingClient.getApplicationMainFrame(),
+ "Server is not starated!");
+ System.exit(1);
}
}
return instance;
=======================================
---
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingClient/src/main/java/org/mozzes/application/remoting/client/RemoteClientConfiguration.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingClient/src/main/java/org/mozzes/application/remoting/client/RemoteClientConfiguration.java
Sat Dec 1 15:14:30 2012
@@ -18,16 +18,18 @@
* along with mozzes. If not, see <
http://www.gnu.org/licenses/>.
*
*/
+
package org.mozzes.application.remoting.client;
import org.mozzes.application.common.client.MozzesClientConfiguration;
import org.mozzes.application.common.session.SessionIdProvider;
import org.mozzes.invocation.common.handler.InvocationHandler;
import org.mozzes.remoting.client.core.DefaultRemotingClientFactory;
-import org.mozzes.remoting.client.pool.RemotingClientPool;
+import org.mozzes.remoting.client.simple.SimpleClientProvider;
+
import org.mozzes.remoting.common.RemotingActionExecutorProvider;
import org.mozzes.remoting.common.RemotingConfiguration;
-
+import org.mozzes.remoting.common.RemotingException;
/**
* The Class RemoteClientConfiguration extends basic {@link
MozzesClientConfiguration} with the remoting executor
@@ -37,15 +39,23 @@
public class RemoteClientConfiguration extends MozzesClientConfiguration {
/** The client provider. */
- private final RemotingActionExecutorProvider clientProvider;
+ private RemotingActionExecutorProvider clientProvider;
- public RemoteClientConfiguration(String serverHost, int serverPort) {
- this(serverHost, serverPort, 1);
+ /**
+ * Client configuration that can choose to use pool or not
+ * @param serverHost Host name to connect to
+ * @param serverPort Port to connect to
+ * @throws RemotingException If client configuration can't be created
+ */
+ public RemoteClientConfiguration(String serverHost, int serverPort,
boolean reconnect) throws RemotingException {
+ setClientProvider(
+ new SimpleClientProvider(
+ new RemotingConfiguration(serverHost, Integer.valueOf(serverPort),
reconnect),
+ new DefaultRemotingClientFactory()));
}
- public RemoteClientConfiguration(String serverHost, int serverPort, int
clientPoolSize) {
- this.clientProvider = new RemotingClientPool(new
RemotingConfiguration(serverHost, Integer.valueOf(serverPort)),
- new DefaultRemotingClientFactory(), clientPoolSize);
+ public void setClientProvider(RemotingActionExecutorProvider
clientProvider) {
+ this.clientProvider = clientProvider;
}
/*
=======================================
---
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingPlugin.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingPlugin.java
Sat Dec 1 15:14:30 2012
@@ -1,3 +1,23 @@
+/*
+ * Copyright 2010 Mozzart
+ *
+ *
+ * This file is part of mozzes.
+ *
+ * mozzes 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * mozzes 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 mozzes. If not, see <
http://www.gnu.org/licenses/>.
+ *
+ */
/*
* Copyright 2010 Mozzart
*
@@ -27,7 +47,6 @@
import org.mozzes.application.plugin.ApplicationPlugin;
import com.google.inject.Binder;
-import com.google.inject.Scopes;
/**
* Module that adds remoting support to the Mozzes server so clients can
connect via the mozzes remoting to the mozzes
@@ -55,9 +74,6 @@
*/
@Override
public void doCustomBinding(Binder binder) {
- binder.bind(InvocationActionExecutor.class).in(Scopes.SINGLETON);
- binder.bind(InvocationActionMapping.class).in(Scopes.SINGLETON);
- binder.bind(InvocationExecutorProvider.class).in(Scopes.SINGLETON);
binder.bind(int.class).annotatedWith(RemotingServerPort.class).toInstance(Integer.valueOf(serverPort));
}
=======================================
---
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingServerListener.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesApplication/mozzesApplicationRemoting/mozzesApplicationRemotingServer/src/main/java/org/mozzes/application/remoting/server/RemotingServerListener.java
Sat Dec 1 15:14:30 2012
@@ -22,15 +22,15 @@
import java.io.IOException;
-import org.mozzes.application.module.ServerInitializationException;
-import org.mozzes.application.module.ServerLifecycleListener;
-import org.mozzes.remoting.server.RemotingServer;
-import org.mozzes.remoting.server.RemotingServerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Injector;
+import org.mozzes.application.module.ServerInitializationException;
+import org.mozzes.application.module.ServerLifecycleListener;
+import org.mozzes.remoting.server.RemotingServer;
+import org.mozzes.remoting.server.RemotingServerFactory;
/**
* Listener that waits on the socket for remote invocations that are
actually remote invocations of server's services.
@@ -57,12 +57,15 @@
/*
* (non-Javadoc)
*
- * @see org.mozzes.application.module.ServerListener#serverStarted()
+ * @see com.mozzes.application.module.ServerListener#serverStarted()
*/
@Override
public void startup() throws ServerInitializationException {
+ InvocationActionMapping mappings =
injector.getInstance(InvocationActionMapping.class);
+
RemotingServer remotingServer =
RemotingServerFactory.getServer(serverPort);
-
remotingServer.addActionMapping(injector.getInstance(InvocationActionMapping.class));
+ remotingServer.addActionMapping(mappings);
+
try {
remotingServer.startServer();
logger.info("Remoting server started on port " + serverPort);
@@ -79,7 +82,7 @@
/*
* (non-Javadoc)
*
- * @see org.mozzes.application.module.ServerListener#serverStopped()
+ * @see com.mozzes.application.module.ServerListener#serverStopped()
*/
@Override
public void shutdown() {
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingClient.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingClient.java
Sat Dec 1 15:14:30 2012
@@ -35,21 +35,21 @@
/**
* Connects with remoting server
*
- * @throws RemotingException If remoting server is not available or any
network problem while trying to establish
- * connection
+ * @throws RemotingException If remoting server is not available or any
network problem while trying to
+ * establish connection
*/
- public void connect() throws RemotingException;
+ void connect() throws RemotingException;
/**
* Disconnects from remoting server. If connection was not established,
should not do anything. Any stream and
* socket must be closed after this method is executed
*/
- public void disconnect();
+ void disconnect();
/**
* Query the connection state
*
* @return <code>true</code> if connection is established,
<code>false</code> otherwise
*/
- public boolean isConnected();
+ boolean isConnected();
}
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingClientFactory.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingClientFactory.java
Sat Dec 1 15:14:30 2012
@@ -23,7 +23,6 @@
import org.mozzes.remoting.client.core.DefaultRemotingClientFactory;
import org.mozzes.remoting.common.RemotingConfiguration;
-
/**
* Interface that all factory form creating remoting clients should
implement. For default implementation, look at
* {@link DefaultRemotingClientFactory}
@@ -33,10 +32,11 @@
*/
public interface RemotingClientFactory {
- /**
- * Creates remoting client
- *
- * @return RemotingClient
- */
- public RemotingClient create(RemotingConfiguration
remotingConfiguration);
+ /**
+ * Creates remoting client
+ *
+ * @param remotingConfiguration Remoting configuration with which client
should be created
+ * @return RemotingClient
+ */
+ RemotingClient create(RemotingConfiguration remotingConfiguration);
}
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingExecutorProviderFactory.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/RemotingExecutorProviderFactory.java
Sat Dec 1 15:14:30 2012
@@ -24,17 +24,16 @@
import java.util.concurrent.ConcurrentMap;
import org.mozzes.remoting.client.ondemand.RemotingOnDemandClientProvider;
-import org.mozzes.remoting.client.pool.RemotingClientPool;
+
import org.mozzes.remoting.common.RemotingActionExecutorProvider;
import org.mozzes.remoting.common.RemotingConfiguration;
-
/**
* Main class for utilizing remoting clients providers. <br>
- * Clients first need to configure pool with either of two supplied
methods:
- * {@link #addProvider(String, int, int)} and {@link #addProvider(String,
int)}.
- * First one configures factory to return pool provider and former
on-demand providers. Remote action executor can then
- * be picked from providers with {@link
RemotingActionExecutorProvider#get()}. Nothing else is required from
clients.
+ * Clients first need to configure pool with either of two supplied
methods: {@link #addProvider(String, int, int)} and
+ * {@link #addProvider(String, int)}. First one configures factory to
return pool provider and former on-demand
+ * providers. Remote action executor can then be picked from providers
with {@link RemotingActionExecutorProvider#get()}
+ * . Nothing else is required from clients.
*
* <p>
* This class is thread-safe
@@ -44,78 +43,69 @@
*/
public class RemotingExecutorProviderFactory {
- /** map of configuration -> executor provider */
- private ConcurrentMap<RemotingConfiguration,
RemotingActionExecutorProvider> pools = new
ConcurrentHashMap<RemotingConfiguration, RemotingActionExecutorProvider>();
+ /** map of configuration -> executor provider */
+ private ConcurrentMap<RemotingConfiguration,
RemotingActionExecutorProvider> pools =
+ new ConcurrentHashMap<RemotingConfiguration,
RemotingActionExecutorProvider>();
- /** Factory for creating remoting clients */
- private final RemotingClientFactory clientFactory;
+ /** Factory for creating remoting clients */
+ private final RemotingClientFactory clientFactory;
- /**
- * Default constructor
- */
- public RemotingExecutorProviderFactory(RemotingClientFactory
clientFactory) {
- this.clientFactory = clientFactory;
- }
+ /**
+ * Default constructor
+ *
+ * @param clientFactory Client factory with which this executor should be
created
+ */
+ public RemotingExecutorProviderFactory(RemotingClientFactory
clientFactory) {
+ this.clientFactory = clientFactory;
+ }
- /**
- * Adds new configuration to factory that will use pool to provide
remoting clients. Pool is good when we know that
- * large number of users/threads will execute action on remoting
server and this minimize overhead needed for
- * constant connection/disconnecting. If identical configuration
already exists, throws
- * {@link IllegalArgumentException}
- *
- * @param host server address
- * @param port server listening port
- * @param poolSize Maximum size of the pool for this configuration
- */
- public RemotingExecutorProviderFactory addProvider(String host, int
port, int poolSize) {
- RemotingConfiguration configuration = new
RemotingConfiguration(host, port);
- if (poolSize <= 0) {
- addConfiguration(configuration, new
RemotingOnDemandClientProvider(configuration, clientFactory));
- } else {
- addConfiguration(configuration, new
RemotingClientPool(configuration, clientFactory, poolSize));
- }
- return this;
- }
+ /**
+ * Adds new configuration to factory that will return on-demand
providers. On-demand providers should be used
+ * when very small number of actions is going to be executed on remoting
server If identical configuration
+ * already exists, throws {@link IllegalArgumentException}
+ *
+ * @param host server address
+ * @param port server listening port
+ * @return This object for chaining
+ */
+ public RemotingExecutorProviderFactory addProvider(String host, int port)
{
+ RemotingConfiguration configuration = new RemotingConfiguration(host,
port);
+ addConfiguration(configuration,
+ new RemotingOnDemandClientProvider(configuration, clientFactory));
+ return this;
+ }
- /**
- * Adds new configuration to factory that will return on-demand
providers. On-demand providers should be used when
- * very small number of actions is going to be executed on remoting
server If identical configuration already
- * exists, throws {@link IllegalArgumentException}
- */
- public RemotingExecutorProviderFactory addProvider(String host, int
port) {
- addProvider(host, port, 0);
- return this;
- }
+ /**
+ * Maps configuration with supplied provider
+ */
+ private void addConfiguration(RemotingConfiguration configuration,
+ RemotingActionExecutorProvider executorProvider) {
+ if (pools.putIfAbsent(configuration, executorProvider) != null) {
+ throw new IllegalArgumentException("Configuration already exists");
+ }
+ }
- /**
- * Maps configuration with supplied provider
- */
- private void addConfiguration(RemotingConfiguration configuration,
RemotingActionExecutorProvider executorProvider) {
- if (pools.putIfAbsent(configuration, executorProvider) != null) {
- throw new IllegalArgumentException("Configuration already
exists");
- }
- }
+ /**
+ * @param configuration Configuration clients wants to check for existance
+ * @return <code>true</code> if specified configuration already exists,
<code>false</code> otherwise
+ */
+ public boolean configurationExists(RemotingConfiguration configuration) {
+ return pools.containsKey(configuration);
+ }
- /**
- * @return <code>true</code> if specified configuration already
exists, <code>false</code> otherwise
- */
- public boolean configurationExists(RemotingConfiguration
configuration) {
- return pools.containsKey(configuration);
- }
-
- /**
- * Gets the action execution provider for specified configuration. If
this configuration is not previously
- * configured with this manager, {@link IllegalArgumentException} is
thrown
- *
- * @param host server address
- * @param port server listening port
- * @return Provider that knows how to provide remoting clients form
given configuration
- */
- public RemotingActionExecutorProvider
getActionExecutionProvider(String host, int port) {
- RemotingActionExecutorProvider pool = pools.get(new
RemotingConfiguration(host, port));
- if (pool == null) {
- throw new IllegalArgumentException("Configuration does not
exists");
- }
- return pool;
- }
+ /**
+ * Gets the action execution provider for specified configuration. If
this configuration is not previously
+ * configured with this manager, {@link IllegalArgumentException} is
thrown
+ *
+ * @param host server address
+ * @param port server listening port
+ * @return Provider that knows how to provide remoting clients form given
configuration
+ */
+ public RemotingActionExecutorProvider getActionExecutionProvider(String
host, int port) {
+ RemotingActionExecutorProvider pool = pools.get(new
RemotingConfiguration(host, port));
+ if (pool == null) {
+ throw new IllegalArgumentException("Configuration does not exists");
+ }
+ return pool;
+ }
}
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/core/RemotingClientImpl.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/core/RemotingClientImpl.java
Sat Dec 1 15:14:30 2012
@@ -26,13 +26,13 @@
import org.mozzes.remoting.client.RemotingClient;
import org.mozzes.remoting.client.RemotingExecutorProviderFactory;
+
import org.mozzes.remoting.common.RemotingAction;
import org.mozzes.remoting.common.RemotingConfiguration;
import org.mozzes.remoting.common.RemotingException;
import org.mozzes.remoting.common.RemotingProtocol;
import org.mozzes.remoting.common.RemotingResponse;
-
/**
* Implementation of remoting client. This client, when provided with
configuration connects to remoting server and can
* execute action on it. Connection is through sockets. Disconnect must be
done when client is no longer needed. General
@@ -110,13 +110,14 @@
if (connectionEstablished) {
connectionEstablished = false;
- if (remotingProtocol != null)
+ if (remotingProtocol != null)
remotingProtocol.close();
if (clientSocket != null) {
try {
clientSocket.close();
} catch (IOException ex) {
+ // ignore
}
clientSocket = null;
}
@@ -136,11 +137,17 @@
try {
remotingProtocol.send(action);
+ return receiveResponse();
+
} catch (IOException ex) {
- throw new RemotingException(ex);
+
+ if(!configuration.isReconnect())
+ throw new RemotingException(ex);
+
+ connectionEstablished = false;
+ connect();
}
-
- return receiveResponse();
+ return execute(action);
}
private RemotingResponse receiveResponse() throws RemotingException {
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/ondemand/RemotingOnDemandClientProvider.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/main/java/org/mozzes/remoting/client/ondemand/RemotingOnDemandClientProvider.java
Sat Dec 1 15:14:30 2012
@@ -25,29 +25,31 @@
import org.mozzes.remoting.common.RemotingActionExecutorProvider;
import org.mozzes.remoting.common.RemotingConfiguration;
-
/**
* Executor provider that always return on-demand executor
*
* @author Kokan
*/
public class RemotingOnDemandClientProvider implements
RemotingActionExecutorProvider {
- /** Client factory that we provide to on-demand client */
- private final RemotingClientFactory clientFactory;
+ /** Client factory that we provide to on-demand client */
+ private final RemotingClientFactory clientFactory;
- private final RemotingConfiguration remotingConfiguration;
+ private final RemotingConfiguration remotingConfiguration;
- /**
- * Default constructor that takes client factory
- */
- public RemotingOnDemandClientProvider(RemotingConfiguration
remotingConfiguration,
- RemotingClientFactory clientFactory) {
- this.clientFactory = clientFactory;
- this.remotingConfiguration = remotingConfiguration;
- }
+ /**
+ * Default constructor that takes client factory
+ *
+ * @param remotingConfiguration Remote configuration with which on demand
client should be created
+ * @param clientFactory Facory for creating on demand clients
+ */
+ public RemotingOnDemandClientProvider(RemotingConfiguration
remotingConfiguration,
+ RemotingClientFactory clientFactory) {
+ this.clientFactory = clientFactory;
+ this.remotingConfiguration = remotingConfiguration;
+ }
- @Override
- public RemotingActionExecutor get() {
- return new RemotingClientOnDemand(remotingConfiguration,
clientFactory);
- }
+ @Override
+ public RemotingActionExecutor get() {
+ return new RemotingClientOnDemand(remotingConfiguration, clientFactory);
+ }
}
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingClient/src/test/java/org/mozzes/remoting/client/pool/RemotingExecutorPoolManagerConfigurationTest.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingClient/src/test/java/org/mozzes/remoting/client/pool/RemotingExecutorPoolManagerConfigurationTest.java
Sat Dec 1 15:14:30 2012
@@ -66,7 +66,7 @@
/* adds new configurations */
for (int i = 1000; i < 2000; i++) {
try {
- providerFactory.addProvider("localhost", i, 10);
+ providerFactory.addProvider("localhost", i);
} catch (Throwable t) {
fail();
}
@@ -91,14 +91,14 @@
public void testAddWhenConfigurationExists() {
RemotingExecutorProviderFactory providerFactory = new
RemotingExecutorProviderFactory(
new MockupRemotingClientFactory(1));
- providerFactory.addProvider("localhost", 10000, 10);
+ providerFactory.addProvider("localhost", 10000);
try {
- providerFactory.addProvider("localhost", 10000, 10);
+ providerFactory.addProvider("localhost", 10000);
fail();
} catch (Throwable t) {
}
try {
- providerFactory.addProvider("localhost", 10000, 10);
+ providerFactory.addProvider("localhost", 10000);
fail();
} catch (Throwable t) {
}
=======================================
--- /trunk/mozzesRemoting/mozzesRemotingCommon/pom.xml Tue Feb 23 16:09:19
2010
+++ /trunk/mozzesRemoting/mozzesRemotingCommon/pom.xml Sat Dec 1 15:14:30
2012
@@ -9,4 +9,11 @@
<artifactId>mozzesRemotingCommon</artifactId>
<name>Mozzes Remoting Common</name>
<description>Mozzes remoting framework common classes</description>
+ <dependencies>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty</artifactId>
+ <version>3.5.10.Final</version>
+ </dependency>
+ </dependencies>
</project>
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingAction.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingAction.java
Sat Dec 1 15:14:30 2012
@@ -20,52 +20,81 @@
*/
package org.mozzes.remoting.common;
-import java.io.*;
-import java.util.*;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Map;
+
+import org.mozzes.remoting.common.netty.Unique;
+
/**
* Encapsulates concrete action remoting client sends to remoting server
*
* @author Perica Milosevic
*/
-public final class RemotingAction implements Serializable {
+public final class RemotingAction implements Unique, Serializable {
- private static final long serialVersionUID = -806957954023327547L;
+ private static final long serialVersionUID = -806957954023327547L;
- /** Name of the action that clients wants to execute */
- private final String actionName;
+ /** Name of the action that clients wants to execute */
+ private final String actionName;
+
+ private Long id;
- /** Action parameters represented as Map */
- private Map<? extends Object, ? extends Object> actionParams = null;
+ /** Action parameters represented as Map */
+ private Map<? extends Object, ? extends Object> actionParams = null;
- public RemotingAction(String actionName, Map<? extends Object, ?
extends Object> actionParams) {
- if (actionName == null)
- throw new IllegalArgumentException("Invalid action name -
null");
+ /**
+ * Default constructor for action
+ *
+ * @param actionName Name of this action
+ * @param actionParams Parameters of this action
+ */
+ public RemotingAction(String actionName, Map<? extends Object, ? extends
Object> actionParams) {
+ if (actionName == null)
+ throw new IllegalArgumentException("Invalid action name - null");
- this.actionName = actionName;
- this.actionParams = actionParams;
- }
+ this.actionName = actionName;
+ this.actionParams = actionParams;
+ }
+
+ /**
+ * @return Name of this action
+ */
+ public String getActionName() {
+ return actionName;
+ }
+
+ /**
+ * @return Parameters of this action
+ */
+ public Map<? extends Object, ? extends Object> getParams() {
+ return Collections.unmodifiableMap(actionParams);
+ }
- public String getActionName() {
- return actionName;
- }
+ /**
+ * @param key Key to retrieve object from parameters
+ * @return Specified parameter based on parameter key
+ */
+ public Object getParam(Object key) {
+ if (actionParams == null)
+ return null;
+ return actionParams.get(key);
+ }
- public Map<? extends Object, ? extends Object> getParams() {
- return Collections.unmodifiableMap(actionParams);
- }
+ @Override
+ public String toString() {
+ return getActionName();
+ }
- /**
- * Returns specified parameter based on parameter key
- */
- public Object getParam(Object key) {
- if (actionParams == null)
- return null;
- return actionParams.get(key);
- }
+ @Override
+ public void setId(Long id) {
+
this.id = id;
+ }
- @Override
- public String toString() {
- return getActionName();
- }
+ @Override
+ public Long getId() {
+ return id;
+ }
}
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingConfiguration.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingConfiguration.java
Sat Dec 1 15:14:30 2012
@@ -28,56 +28,88 @@
*/
public class RemotingConfiguration {
- /** hostname of remoting server */
- private final String host;
+ /** hostname of remoting server */
+ private final String host;
- /** port of remoting server */
- private final Integer port;
+ /** port of remoting server */
+ private final Integer port;
- /**
- * Construction of remoting configuration with specified hostname and
port
- */
- public RemotingConfiguration(String host, Integer port) {
- this.host = host;
- this.port = port;
- }
+ /** should client try to recconect if connection becomes broken */
+ private boolean reconnect;
+
+ /**
+ * Construction of remoting configuration with specified hostname and port
+ *
+ * @param host Hostname to connect to
+ * @param port Port to connect to
+ */
+ public RemotingConfiguration(String host, Integer port) {
+ this(host, port, false);
+ }
+
+ /**
+ * Construction of remoting configuration with specified hostname and port
+ *
+ * @param host Hostname to connect to
+ * @param port Port to connect to
+ */
+ public RemotingConfiguration(String host, Integer port, boolean
reconnect) {
+ this.reconnect = reconnect;
+ this.port = port;
+ this.host = host;
+ }
- public String getHost() {
- return host;
+ /**
+ * @return should client try to recconect if connection becomes broken
+ */
+ public boolean isReconnect() {
+ return reconnect;
}
- public Integer getPort() {
- return port;
- }
+ /**
+ * @return Hostname to connect to
+ */
+ public String getHost() {
+ return host;
+ }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((host == null) ? 0 : host.hashCode());
- result = prime * result + ((port == null) ? 0 : port.hashCode());
- return result;
- }
+ /**
+ * @return Port to connect to
+ */
+ public Integer getPort() {
+ return port;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ if (host != null)
+ result = prime * result + host.hashCode();
+ if (port != null)
+ result = prime * result + port.hashCode();
+ return result;
+ }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (!(obj instanceof RemotingConfiguration))
- return false;
- final RemotingConfiguration other = (RemotingConfiguration) obj;
- if (host == null) {
- if (other.host != null)
- return false;
- } else if (!host.equals(other.host))
- return false;
- if (port == null) {
- if (other.port != null)
- return false;
- } else if (!port.equals(other.port))
- return false;
- return true;
- }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof RemotingConfiguration))
+ return false;
+ final RemotingConfiguration other = (RemotingConfiguration) obj;
+ if (host == null) {
+ if (other.host != null)
+ return false;
+ } else if (!host.equals(other.host))
+ return false;
+ if (port == null) {
+ if (other.port != null)
+ return false;
+ } else if (!port.equals(other.port))
+ return false;
+ return true;
+ }
}
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingException.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingException.java
Sat Dec 1 15:14:30 2012
@@ -20,28 +20,67 @@
*/
package org.mozzes.remoting.common;
+import org.mozzes.remoting.common.netty.Unique;
+
/**
* Represents all possible exception that can happen in remoting
client/server communication
*
* @author Perica Milosevic
*/
-public class RemotingException extends Exception {
+public class RemotingException extends Exception implements Unique {
private static final long serialVersionUID = 4540834361558254985L;
+
+ private Long id;
+ /**
+ * Default constructor
+ */
public RemotingException() {
super();
}
+ /**
+ * Constructor with both message and a cause
+ * @param message Exception message
+ * @param cause Exception cause
+ */
public RemotingException(String message, Throwable cause) {
super(message, cause);
}
+ /**
+ * Constructor with message
+ * @param message Exception message
+ */
public RemotingException(String message) {
super(message);
}
+ /**
+ * Constructor with a cause
+ * @param cause Exception cause
+ */
public RemotingException(Throwable cause) {
super(cause);
}
-
+
+ /**
+ * Return id of this remoting response. This remoting response id has the
same ID as the RemotingAction
+ * which response is this object.
+ * @return a unique id which bind this response to remoting action.
+ */
+ @Override
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Set id of this remoting response. This remoting response id has the
same ID as the RemotingAction which response
+ * is this object.
+ * @param id a unique id of the response. Must correspond to id of an
remoting action.
+ */
+ @Override
+ public void setId(Long id) {
+
this.id = id;
+ }
}
=======================================
---
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingProtocol.java
Sat Feb 27 06:56:25 2010
+++
/trunk/mozzesRemoting/mozzesRemotingCommon/src/main/java/org/mozzes/remoting/common/RemotingProtocol.java
Sat Dec 1 15:14:30 2012
@@ -38,7 +38,7 @@
/**
* This class defines protocol of communication between remoting server
and client.
*/
-public class RemotingProtocol {
+public final class RemotingProtocol {
private static final Logger logger =
LoggerFactory.getLogger(RemotingProtocol.class);
@@ -54,6 +54,7 @@
* that is requested by client.
*
* @param socket Communication socket
+ * @return Newly created remoting protocol
* @throws IOException If there is some problem with communication over
socket
*/
public static RemotingProtocol buildServerSide(Socket socket) throws
IOException {
@@ -64,6 +65,7 @@
* Creates new remoting protocol instance for client side use. There will
be no compression or encryption
*
* @param socket Communication socket
+ * @return Newly created remoting protocol
* @throws IOException If there is some problem with communication over
socket
*/
public static RemotingProtocol buildClientSide(Socket socket) throws
IOException {
@@ -76,6 +78,7 @@
* @param socket Communication socket
* @param compression Is compression enabled?
* @param encryption Is encryption enabled? THIS FEATURE IS NOT SUPPORTED
YET, THERE IS NO ENCRYPTION
+ * @return Newly created remoting protocol
* @throws IOException If there is some problem with communication over
socket
*/
public static RemotingProtocol buildClientSide(Socket socket, boolean
compression, boolean encryption)
@@ -97,8 +100,10 @@
createStreams(socket, serverSide);
initCommunication(serverSide, compression, encryption);
if (logger.isDebugEnabled()) {
- logger.debug((serverSide ? "Server" : "Client") + " side remoting
protocol created (compression = "
- + this.compression + ", encryption = " + this.encryption + ")");
+ String type = "Client";
+ if (serverSide) type = "Server";
+ logger.debug(type + " side remoting protocol created (compression = "
+ + this.compression + ", encryption = " + this.encryption + ")");
}
}
@@ -117,6 +122,9 @@
/**
* Receives object from socket according to protocol
+ * @return Received object
+ * @throws IOException If IO exception occurs
+ * @throws RemotingException If there is no data in the stream or class
cannot be found
*/
public synchronized Object receive() throws IOException,
RemotingException {
try {
@@ -147,6 +155,7 @@
try {
dataInputStream.close();
} catch (IOException ex) {
+ // ignore
}
dataInputStream = null;
}
@@ -155,6 +164,7 @@
try {
dataOutputStream.close();
} catch (IOException ex) {
+ // ignore
}
dataOutputStream = null;
}
@@ -171,10 +181,10 @@
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
}
- logger.debug("createStream() streams created");
+ logger.debug("createStream() streams created");
}
- private void initCommunication(boolean serverSide, boolean compression,
boolean encryption) throws IOException {
+ private void initCommunication(boolean serverSide, boolean aCompression,
boolean aEncryption) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("initCommunication() before - serverSide=" + serverSide);
}
@@ -182,8 +192,8 @@
this.compression = dataInputStream.readBoolean();
this.encryption = dataInputStream.readBoolean();
} else {
- this.compression = compression;
- this.encryption = encryption;
+ this.compression = aCompression;
+ this.encryption = aEncryption;
dataOutputStream.writeBoolean(compression);
dataOutputStream.writeBoolean(encryption);
dataOutputStream.flush();
=======================================
***Additional files exist in this changeset.***