From c018166e78adb8b831fe09079bedfd4769cc9ffb Mon Sep 17 00:00:00 2001 From: stefzhlg Date: Thu, 20 Nov 2014 15:55:29 +0800 Subject: [PATCH] first submit first submit --- .classpath | 27 ++ .project | 23 ++ .settings/org.eclipse.core.resources.prefs | 4 + .settings/org.eclipse.jdt.core.prefs | 12 + .settings/org.eclipse.m2e.core.prefs | 4 + README.md | 70 +++++ pom.xml | 91 ++++++ .../java/org/stefan/snrpc/SnRpcClient.java | 9 + .../org/stefan/snrpc/SnRpcConnection.java | 20 ++ .../stefan/snrpc/SnRpcConnectionFactory.java | 11 + .../java/org/stefan/snrpc/SnRpcServer.java | 11 + .../snrpc/client/CommonSnRpcClient.java | 150 +++++++++ .../client/PoolableRpcConnectionFactory.java | 152 +++++++++ .../snrpc/client/SnNettyRpcConnection.java | 172 ++++++++++ .../client/SnNettyRpcConnectionFactory.java | 30 ++ .../org/stefan/snrpc/conf/ConfigureParse.java | 12 + .../org/stefan/snrpc/conf/RpcImplementor.java | 62 ++++ .../org/stefan/snrpc/conf/RpcService.java | 107 +++++++ .../org/stefan/snrpc/conf/SnRpcConfig.java | 105 +++++++ .../stefan/snrpc/conf/XmlConfigureParse.java | 150 +++++++++ .../snrpc/exception/SerializerException.java | 28 ++ .../snrpc/exception/SnRpcException.java | 28 ++ .../org/stefan/snrpc/log/AbstractLogger.java | 256 +++++++++++++++ .../org/stefan/snrpc/log/DefaultLogger.java | 52 ++++ src/main/java/org/stefan/snrpc/log/Level.java | 18 ++ .../org/stefan/snrpc/log/Log4JLogger.java | 80 +++++ .../java/org/stefan/snrpc/log/Logger.java | 189 +++++++++++ .../org/stefan/snrpc/log/LoggerFactory.java | 125 ++++++++ .../java/org/stefan/snrpc/log/SunLogger.java | 111 +++++++ .../AbstractProtostuffSerializer.java | 90 ++++++ .../snrpc/serializer/ClientSerializer.java | 37 +++ .../snrpc/serializer/ProtobufSerializer.java | 32 ++ .../snrpc/serializer/ServerSerializer.java | 35 +++ .../stefan/snrpc/serializer/SnRpcRequest.java | 88 ++++++ .../snrpc/serializer/SnRpcRequestDecoder.java | 37 +++ .../snrpc/serializer/SnRpcRequestEncoder.java | 33 ++ .../snrpc/serializer/SnRpcResponse.java | 55 ++++ .../serializer/SnRpcResponseDecoder.java | 35 +++ .../serializer/SnRpcResponseEncoder.java | 32 ++ .../snrpc/server/ParseXmlToService.java | 25 ++ .../stefan/snrpc/server/SnNettyRpcServer.java | 179 +++++++++++ .../snrpc/server/SnNettyRpcServerHandler.java | 123 ++++++++ .../snrpc/server/StatisticsService.java | 73 +++++ .../org/stefan/snrpc/util/BufferCache.java | 22 ++ .../java/org/stefan/snrpc/util/FileUtil.java | 12 + .../org/stefan/snrpc/util/HandlerMapper.java | 48 +++ .../java/org/stefan/snrpc/util/IOUtils.java | 103 ++++++ .../java/org/stefan/snrpc/util/LRUMap.java | 86 +++++ .../stefan/snrpc/util/MessageFormatter.java | 293 ++++++++++++++++++ .../stefan/snrpc/util/ReflectionCache.java | 89 ++++++ .../org/stefan/snrpc/util/SchemaCache.java | 60 ++++ .../java/org/stefan/snrpc/util/Sequence.java | 21 ++ .../org/stefan/snrpc/util/StringUtil.java | 16 + src/test/java/org/stefan/snrpc/Client.java | 28 ++ src/test/java/org/stefan/snrpc/Server.java | 22 ++ .../org/stefan/snrpc/server/SnRpcImpl.java | 12 + .../stefan/snrpc/server/SnRpcInterface.java | 9 + src/test/resources/config.xml | 9 + src/test/resources/snrpcserver.properties | 10 + target/classes/config.xml | 9 + .../org/stefan/snrpc/SnRpcClient.class | Bin 0 -> 296 bytes .../org/stefan/snrpc/SnRpcConnection.class | Bin 0 -> 398 bytes .../stefan/snrpc/SnRpcConnectionFactory.class | Bin 0 -> 321 bytes .../org/stefan/snrpc/SnRpcServer.class | Bin 0 -> 215 bytes .../CommonSnRpcClient$SnRpcInvoker.class | Bin 0 -> 3422 bytes .../snrpc/client/CommonSnRpcClient.class | Bin 0 -> 3901 bytes .../client/PoolableRpcConnectionFactory.class | Bin 0 -> 4803 bytes .../snrpc/client/SnNettyRpcConnection$1.class | Bin 0 -> 2299 bytes .../snrpc/client/SnNettyRpcConnection.class | Bin 0 -> 5754 bytes .../client/SnNettyRpcConnectionFactory.class | Bin 0 -> 1203 bytes .../stefan/snrpc/conf/ConfigureParse.class | Bin 0 -> 252 bytes .../stefan/snrpc/conf/RpcImplementor.class | Bin 0 -> 1451 bytes .../org/stefan/snrpc/conf/RpcService.class | Bin 0 -> 1783 bytes .../org/stefan/snrpc/conf/SnRpcConfig.class | Bin 0 -> 3533 bytes .../stefan/snrpc/conf/XmlConfigureParse.class | Bin 0 -> 6092 bytes .../snrpc/exception/SerializerException.class | Bin 0 -> 834 bytes .../snrpc/exception/SnRpcException.class | Bin 0 -> 819 bytes .../org/stefan/snrpc/log/AbstractLogger.class | Bin 0 -> 3130 bytes .../org/stefan/snrpc/log/DefaultLogger.class | Bin 0 -> 1593 bytes .../classes/org/stefan/snrpc/log/Level.class | Bin 0 -> 1430 bytes .../org/stefan/snrpc/log/Log4JLogger.class | Bin 0 -> 2430 bytes .../classes/org/stefan/snrpc/log/Logger.class | Bin 0 -> 627 bytes .../org/stefan/snrpc/log/LoggerFactory.class | Bin 0 -> 4939 bytes .../org/stefan/snrpc/log/SunLogger.class | Bin 0 -> 3438 bytes .../AbstractProtostuffSerializer.class | Bin 0 -> 3559 bytes .../snrpc/serializer/ClientSerializer.class | Bin 0 -> 443 bytes .../snrpc/serializer/ProtobufSerializer.class | Bin 0 -> 1553 bytes .../snrpc/serializer/ServerSerializer.class | Bin 0 -> 443 bytes .../snrpc/serializer/SnRpcRequest.class | Bin 0 -> 2356 bytes .../serializer/SnRpcRequestDecoder.class | Bin 0 -> 1615 bytes .../serializer/SnRpcRequestEncoder.class | Bin 0 -> 1816 bytes .../snrpc/serializer/SnRpcResponse.class | Bin 0 -> 1478 bytes .../serializer/SnRpcResponseDecoder.class | Bin 0 -> 1626 bytes .../serializer/SnRpcResponseEncoder.class | Bin 0 -> 1824 bytes .../snrpc/server/ParseXmlToService.class | Bin 0 -> 1470 bytes .../snrpc/server/SnNettyRpcServer$1.class | Bin 0 -> 2647 bytes .../snrpc/server/SnNettyRpcServer.class | Bin 0 -> 6544 bytes .../server/SnNettyRpcServerHandler.class | Bin 0 -> 6616 bytes .../snrpc/server/StatisticsService$1.class | Bin 0 -> 2222 bytes .../snrpc/server/StatisticsService.class | Bin 0 -> 2955 bytes .../org/stefan/snrpc/util/BufferCache$1.class | Bin 0 -> 819 bytes .../org/stefan/snrpc/util/BufferCache.class | Bin 0 -> 911 bytes .../org/stefan/snrpc/util/FileUtil.class | Bin 0 -> 789 bytes .../org/stefan/snrpc/util/HandlerMapper.class | Bin 0 -> 2117 bytes .../org/stefan/snrpc/util/IOUtils.class | Bin 0 -> 2015 bytes .../org/stefan/snrpc/util/LRUMap.class | Bin 0 -> 2946 bytes .../stefan/snrpc/util/MessageFormatter.class | Bin 0 -> 6558 bytes .../stefan/snrpc/util/ReflectionCache.class | Bin 0 -> 3720 bytes .../org/stefan/snrpc/util/SchemaCache.class | Bin 0 -> 3068 bytes .../org/stefan/snrpc/util/Sequence.class | Bin 0 -> 639 bytes .../org/stefan/snrpc/util/StringUtil.class | Bin 0 -> 680 bytes target/classes/snrpcserver.properties | 10 + target/test-classes/config.xml | 9 + .../org/stefan/snrpc/Client.class | Bin 0 -> 1732 bytes .../org/stefan/snrpc/Server.class | Bin 0 -> 933 bytes .../org/stefan/snrpc/server/SnRpcImpl.class | Bin 0 -> 729 bytes .../stefan/snrpc/server/SnRpcInterface.class | Bin 0 -> 195 bytes target/test-classes/snrpcserver.properties | 10 + 118 files changed, 3861 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/org/stefan/snrpc/SnRpcClient.java create mode 100644 src/main/java/org/stefan/snrpc/SnRpcConnection.java create mode 100644 src/main/java/org/stefan/snrpc/SnRpcConnectionFactory.java create mode 100644 src/main/java/org/stefan/snrpc/SnRpcServer.java create mode 100644 src/main/java/org/stefan/snrpc/client/CommonSnRpcClient.java create mode 100644 src/main/java/org/stefan/snrpc/client/PoolableRpcConnectionFactory.java create mode 100644 src/main/java/org/stefan/snrpc/client/SnNettyRpcConnection.java create mode 100644 src/main/java/org/stefan/snrpc/client/SnNettyRpcConnectionFactory.java create mode 100644 src/main/java/org/stefan/snrpc/conf/ConfigureParse.java create mode 100644 src/main/java/org/stefan/snrpc/conf/RpcImplementor.java create mode 100644 src/main/java/org/stefan/snrpc/conf/RpcService.java create mode 100644 src/main/java/org/stefan/snrpc/conf/SnRpcConfig.java create mode 100644 src/main/java/org/stefan/snrpc/conf/XmlConfigureParse.java create mode 100644 src/main/java/org/stefan/snrpc/exception/SerializerException.java create mode 100644 src/main/java/org/stefan/snrpc/exception/SnRpcException.java create mode 100644 src/main/java/org/stefan/snrpc/log/AbstractLogger.java create mode 100644 src/main/java/org/stefan/snrpc/log/DefaultLogger.java create mode 100644 src/main/java/org/stefan/snrpc/log/Level.java create mode 100644 src/main/java/org/stefan/snrpc/log/Log4JLogger.java create mode 100644 src/main/java/org/stefan/snrpc/log/Logger.java create mode 100644 src/main/java/org/stefan/snrpc/log/LoggerFactory.java create mode 100644 src/main/java/org/stefan/snrpc/log/SunLogger.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/AbstractProtostuffSerializer.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/ClientSerializer.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/ProtobufSerializer.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/ServerSerializer.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/SnRpcRequest.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/SnRpcRequestDecoder.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/SnRpcRequestEncoder.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/SnRpcResponse.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/SnRpcResponseDecoder.java create mode 100644 src/main/java/org/stefan/snrpc/serializer/SnRpcResponseEncoder.java create mode 100644 src/main/java/org/stefan/snrpc/server/ParseXmlToService.java create mode 100644 src/main/java/org/stefan/snrpc/server/SnNettyRpcServer.java create mode 100644 src/main/java/org/stefan/snrpc/server/SnNettyRpcServerHandler.java create mode 100644 src/main/java/org/stefan/snrpc/server/StatisticsService.java create mode 100644 src/main/java/org/stefan/snrpc/util/BufferCache.java create mode 100644 src/main/java/org/stefan/snrpc/util/FileUtil.java create mode 100644 src/main/java/org/stefan/snrpc/util/HandlerMapper.java create mode 100644 src/main/java/org/stefan/snrpc/util/IOUtils.java create mode 100644 src/main/java/org/stefan/snrpc/util/LRUMap.java create mode 100644 src/main/java/org/stefan/snrpc/util/MessageFormatter.java create mode 100644 src/main/java/org/stefan/snrpc/util/ReflectionCache.java create mode 100644 src/main/java/org/stefan/snrpc/util/SchemaCache.java create mode 100644 src/main/java/org/stefan/snrpc/util/Sequence.java create mode 100644 src/main/java/org/stefan/snrpc/util/StringUtil.java create mode 100644 src/test/java/org/stefan/snrpc/Client.java create mode 100644 src/test/java/org/stefan/snrpc/Server.java create mode 100644 src/test/java/org/stefan/snrpc/server/SnRpcImpl.java create mode 100644 src/test/java/org/stefan/snrpc/server/SnRpcInterface.java create mode 100644 src/test/resources/config.xml create mode 100644 src/test/resources/snrpcserver.properties create mode 100644 target/classes/config.xml create mode 100644 target/classes/org/stefan/snrpc/SnRpcClient.class create mode 100644 target/classes/org/stefan/snrpc/SnRpcConnection.class create mode 100644 target/classes/org/stefan/snrpc/SnRpcConnectionFactory.class create mode 100644 target/classes/org/stefan/snrpc/SnRpcServer.class create mode 100644 target/classes/org/stefan/snrpc/client/CommonSnRpcClient$SnRpcInvoker.class create mode 100644 target/classes/org/stefan/snrpc/client/CommonSnRpcClient.class create mode 100644 target/classes/org/stefan/snrpc/client/PoolableRpcConnectionFactory.class create mode 100644 target/classes/org/stefan/snrpc/client/SnNettyRpcConnection$1.class create mode 100644 target/classes/org/stefan/snrpc/client/SnNettyRpcConnection.class create mode 100644 target/classes/org/stefan/snrpc/client/SnNettyRpcConnectionFactory.class create mode 100644 target/classes/org/stefan/snrpc/conf/ConfigureParse.class create mode 100644 target/classes/org/stefan/snrpc/conf/RpcImplementor.class create mode 100644 target/classes/org/stefan/snrpc/conf/RpcService.class create mode 100644 target/classes/org/stefan/snrpc/conf/SnRpcConfig.class create mode 100644 target/classes/org/stefan/snrpc/conf/XmlConfigureParse.class create mode 100644 target/classes/org/stefan/snrpc/exception/SerializerException.class create mode 100644 target/classes/org/stefan/snrpc/exception/SnRpcException.class create mode 100644 target/classes/org/stefan/snrpc/log/AbstractLogger.class create mode 100644 target/classes/org/stefan/snrpc/log/DefaultLogger.class create mode 100644 target/classes/org/stefan/snrpc/log/Level.class create mode 100644 target/classes/org/stefan/snrpc/log/Log4JLogger.class create mode 100644 target/classes/org/stefan/snrpc/log/Logger.class create mode 100644 target/classes/org/stefan/snrpc/log/LoggerFactory.class create mode 100644 target/classes/org/stefan/snrpc/log/SunLogger.class create mode 100644 target/classes/org/stefan/snrpc/serializer/AbstractProtostuffSerializer.class create mode 100644 target/classes/org/stefan/snrpc/serializer/ClientSerializer.class create mode 100644 target/classes/org/stefan/snrpc/serializer/ProtobufSerializer.class create mode 100644 target/classes/org/stefan/snrpc/serializer/ServerSerializer.class create mode 100644 target/classes/org/stefan/snrpc/serializer/SnRpcRequest.class create mode 100644 target/classes/org/stefan/snrpc/serializer/SnRpcRequestDecoder.class create mode 100644 target/classes/org/stefan/snrpc/serializer/SnRpcRequestEncoder.class create mode 100644 target/classes/org/stefan/snrpc/serializer/SnRpcResponse.class create mode 100644 target/classes/org/stefan/snrpc/serializer/SnRpcResponseDecoder.class create mode 100644 target/classes/org/stefan/snrpc/serializer/SnRpcResponseEncoder.class create mode 100644 target/classes/org/stefan/snrpc/server/ParseXmlToService.class create mode 100644 target/classes/org/stefan/snrpc/server/SnNettyRpcServer$1.class create mode 100644 target/classes/org/stefan/snrpc/server/SnNettyRpcServer.class create mode 100644 target/classes/org/stefan/snrpc/server/SnNettyRpcServerHandler.class create mode 100644 target/classes/org/stefan/snrpc/server/StatisticsService$1.class create mode 100644 target/classes/org/stefan/snrpc/server/StatisticsService.class create mode 100644 target/classes/org/stefan/snrpc/util/BufferCache$1.class create mode 100644 target/classes/org/stefan/snrpc/util/BufferCache.class create mode 100644 target/classes/org/stefan/snrpc/util/FileUtil.class create mode 100644 target/classes/org/stefan/snrpc/util/HandlerMapper.class create mode 100644 target/classes/org/stefan/snrpc/util/IOUtils.class create mode 100644 target/classes/org/stefan/snrpc/util/LRUMap.class create mode 100644 target/classes/org/stefan/snrpc/util/MessageFormatter.class create mode 100644 target/classes/org/stefan/snrpc/util/ReflectionCache.class create mode 100644 target/classes/org/stefan/snrpc/util/SchemaCache.class create mode 100644 target/classes/org/stefan/snrpc/util/Sequence.class create mode 100644 target/classes/org/stefan/snrpc/util/StringUtil.class create mode 100644 target/classes/snrpcserver.properties create mode 100644 target/test-classes/config.xml create mode 100644 target/test-classes/org/stefan/snrpc/Client.class create mode 100644 target/test-classes/org/stefan/snrpc/Server.class create mode 100644 target/test-classes/org/stefan/snrpc/server/SnRpcImpl.class create mode 100644 target/test-classes/org/stefan/snrpc/server/SnRpcInterface.class create mode 100644 target/test-classes/snrpcserver.properties diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..4a3ff26 --- /dev/null +++ b/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..b3d72bc --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + snrpc + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..f9fe345 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/test/java=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..6249222 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a8ffd5 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +SNRPC + +-------------------- + -- a simple netty RPC framework + use protostuff-1.07 for serializer,use netty-3.2.1 for nio. + + ##How to use + + e.g. + + 1, interface and implementor + // define an interface: + public interface SnRpcInterface { + public String getMessage(String param); + } + + // implement interface + public class SnRpcImpl implements SnRpcInterface { + public String getMessage(String param) { + return "hi,it is message from server...param+" + param; + } + } + +2, start server + + SnRpcInterface inter = new SnRpcImpl(); + SnRpcServer server = new SnNettyRpcServer(new Object[] { inter }); + try { + server.start(); + } catch (Throwable e) { + e.printStackTrace(); + } + +3, client invoker + + SnRpcConnectionFactory factory = new SnNettyRpcConnectionFactory( + "localhost", 8080); + factory = new PoolableRpcConnectionFactory(factory); + SnRpcClient client = new CommonSnRpcClient(factory); + try { + SnRpcInterface clazz = client.proxy(SnRpcInterface.class); + String message = clazz.getMessage("come on"); + System.out.println("client receive message .... : " + message); + } catch (Throwable e) { + e.printStackTrace(); + } + +## Pre-requirement + +* JDK6+ +* Maven 2 + + + +# Dependency + +* reflectasm-1.07.jar +* asm-4.0.jar +* log4j-1.2.16.jar +* dom4j-1.6.1.jar +* xml-apis-1.0.b2.jar +* slf4j-api-1.6.6.jar +* netty-3.2.1.Final.jar +* jaxen-1.1.6.jar +* protostuff-core-1.0.7.jar +* protostuff-api-1.0.7.jar +* protostuff-runtime-1.0.7.jar +* protostuff-collectionschema-1.0.7.jar +* commons-pool-1.6.jar + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..550f793 --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + 4.0.0 + + org.stefan + snrpc + 0.0.1-SNAPSHOT + jar + + faraway + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + com.esotericsoftware.reflectasm + reflectasm + 1.07 + + + log4j + log4j + 1.2.16 + runtime + + + dom4j + dom4j + 1.6.1 + + + org.slf4j + slf4j-api + 1.6.6 + true + provided + + + org.jboss.netty + netty + 3.2.1.Final + + + javax.servlet + servlet-api + + + commons-logging + commons-logging + + + true + provided + + + jaxen + jaxen + 1.1.6 + + + com.dyuproject.protostuff + protostuff-core + 1.0.7 + true + provided + + + com.dyuproject.protostuff + protostuff-runtime + 1.0.7 + true + provided + + + commons-pool + commons-pool + 1.6 + true + provided + + + diff --git a/src/main/java/org/stefan/snrpc/SnRpcClient.java b/src/main/java/org/stefan/snrpc/SnRpcClient.java new file mode 100644 index 0000000..03b4537 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/SnRpcClient.java @@ -0,0 +1,9 @@ +package org.stefan.snrpc; + +/** + * @author zhaoliangang 2014-11-13 + */ +public interface SnRpcClient { + + public T proxy(Class interfaceClass) throws Throwable; +} diff --git a/src/main/java/org/stefan/snrpc/SnRpcConnection.java b/src/main/java/org/stefan/snrpc/SnRpcConnection.java new file mode 100644 index 0000000..5157005 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/SnRpcConnection.java @@ -0,0 +1,20 @@ +package org.stefan.snrpc; + +import org.stefan.snrpc.serializer.SnRpcRequest; +import org.stefan.snrpc.serializer.SnRpcResponse; + +/** + * @author zhaoliangang 2014-11-13 + */ +public interface SnRpcConnection { + + SnRpcResponse sendRequest(SnRpcRequest request) throws Throwable; + + void connection() throws Throwable; + + void close() throws Throwable; + + boolean isConnected(); + + boolean isClosed(); +} diff --git a/src/main/java/org/stefan/snrpc/SnRpcConnectionFactory.java b/src/main/java/org/stefan/snrpc/SnRpcConnectionFactory.java new file mode 100644 index 0000000..26432d6 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/SnRpcConnectionFactory.java @@ -0,0 +1,11 @@ +package org.stefan.snrpc; + +/** + * @author zhaoliangang 2014-11-13 + */ +public interface SnRpcConnectionFactory { + + SnRpcConnection getConnection() throws Throwable; + + void recycle(SnRpcConnection connection) throws Throwable; +} diff --git a/src/main/java/org/stefan/snrpc/SnRpcServer.java b/src/main/java/org/stefan/snrpc/SnRpcServer.java new file mode 100644 index 0000000..191f4eb --- /dev/null +++ b/src/main/java/org/stefan/snrpc/SnRpcServer.java @@ -0,0 +1,11 @@ +package org.stefan.snrpc; + +/** + * @author zhaoliangang 2014-11-13 + */ +public interface SnRpcServer { + + void start() throws Throwable; + + void stop() throws Throwable; +} diff --git a/src/main/java/org/stefan/snrpc/client/CommonSnRpcClient.java b/src/main/java/org/stefan/snrpc/client/CommonSnRpcClient.java new file mode 100644 index 0000000..844ddb7 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/client/CommonSnRpcClient.java @@ -0,0 +1,150 @@ +package org.stefan.snrpc.client; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.LinkedList; +import java.util.List; + +import org.stefan.snrpc.SnRpcClient; +import org.stefan.snrpc.SnRpcConnection; +import org.stefan.snrpc.SnRpcConnectionFactory; +import org.stefan.snrpc.log.Logger; +import org.stefan.snrpc.log.LoggerFactory; +import org.stefan.snrpc.serializer.SnRpcRequest; +import org.stefan.snrpc.serializer.SnRpcResponse; +import org.stefan.snrpc.util.Sequence; + +/** + * rpc client + * @author zhaoliangang 2014-11-13 + */ +public class CommonSnRpcClient implements SnRpcClient { + + private static final Logger logger = LoggerFactory + .getLogger(CommonSnRpcClient.class); + + private SnRpcConnectionFactory connectionFactory; + + private SnRpcConnection connection; + + private SnRpcInvoker invoker = new SnRpcInvoker(); + + /** + * @param connectionFactory + */ + public CommonSnRpcClient(SnRpcConnectionFactory connectionFactory) { + if (null == connectionFactory) + throw new NullPointerException("connectionFactory is null..."); + this.connectionFactory = connectionFactory; + } + + /** + * @param connection + */ + public CommonSnRpcClient(SnRpcConnection connection) { + if (null == connection) + throw new NullPointerException("connection is null..."); + this.connection = connection; + } + + /** + * destroy + * @throws Throwable + */ + public void destroy() throws Throwable { + if (null != connection) { + connection.close(); + } + } + + + /** + * generate requestID + * @return + */ + protected String generateRequestID() { + return Sequence.next()+""; + } + + /** + * recycle + * @param connection + */ + private void recycle(SnRpcConnection connection) { + if (null != connection && null != connectionFactory) { + try { + connectionFactory.recycle(connection); + } catch (Throwable t) { + logger.warn("recycle rpc connection fail!", t); + } + } + } + + /** + * get connection + * @return + * @throws Throwable + */ + private SnRpcConnection getConnection() throws Throwable { + if (null != connection) { + if (!connection.isConnected()) { + connection.connection(); + } + return connection; + } else { + return connectionFactory.getConnection(); + } + } + + /* + * proxy + */ + @SuppressWarnings("unchecked") + public T proxy(Class interfaceClass) throws Throwable { + if (!interfaceClass.isInterface()) { + throw new IllegalArgumentException(interfaceClass.getName() + + " is not an interface"); + } + return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), + new Class[] { interfaceClass }, invoker); + } + + + /** + * invoker + */ + private class SnRpcInvoker implements InvocationHandler { + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + String className = method.getDeclaringClass().getName(); + List parameterTypes = new LinkedList(); + for (Class parameterType : method.getParameterTypes()) { + parameterTypes.add(parameterType.getName()); + } + + String requestID = generateRequestID(); + SnRpcRequest request = new SnRpcRequest(requestID, className, + method.getName(), parameterTypes.toArray(new String[0]), + args); + SnRpcConnection connection = null; + SnRpcResponse response = null; + try { + connection = getConnection(); + response = connection.sendRequest(request); + } catch (Throwable t) { + logger.warn("send rpc request fail! request: <{}>", + new Object[] { request }, t); + throw new RuntimeException(t); + } finally { + recycle(connection); + } + + if (response.getException() != null) { + throw response.getException(); + } else { + return response.getResult(); + } + } + } +} diff --git a/src/main/java/org/stefan/snrpc/client/PoolableRpcConnectionFactory.java b/src/main/java/org/stefan/snrpc/client/PoolableRpcConnectionFactory.java new file mode 100644 index 0000000..d6712fe --- /dev/null +++ b/src/main/java/org/stefan/snrpc/client/PoolableRpcConnectionFactory.java @@ -0,0 +1,152 @@ +package org.stefan.snrpc.client; + +import org.apache.commons.pool.PoolableObjectFactory; +import org.apache.commons.pool.impl.GenericObjectPool; +import org.stefan.snrpc.SnRpcConnection; +import org.stefan.snrpc.SnRpcConnectionFactory; + +/** + * connection poolable + * + * @author zhaoliangang 2014-11-14 + */ +public class PoolableRpcConnectionFactory implements SnRpcConnectionFactory, + PoolableObjectFactory { + //connectionFactory + private SnRpcConnectionFactory connectionFactory; + + //org.apache.commons.pool + private GenericObjectPool pool = new GenericObjectPool( + this); + + public PoolableRpcConnectionFactory(SnRpcConnectionFactory factory) { + if (null == factory) { + throw new NullPointerException("factory"); + } + this.connectionFactory = factory; + } + + /* get Connection + * @see org.stefan.snrpc.SnRpcConnectionFactory#getConnection() + */ + public SnRpcConnection getConnection() throws Throwable { + return pool.borrowObject(); + } + + /* recycle connection pool + * @see org.stefan.snrpc.SnRpcConnectionFactory#recycle(org.stefan.snrpc.SnRpcConnection) + */ + public void recycle(SnRpcConnection connection) throws Throwable { + if (null != connection) { + pool.returnObject(connection); + } + } + + /** + * destroy connection pool + * @throws Throwable + */ + public void destroy() throws Throwable { + pool.close(); + } + + /* activate connection + * @see org.apache.commons.pool.PoolableObjectFactory#activateObject(java.lang.Object) + */ + public void activateObject(SnRpcConnection connection) throws Exception { + try { + connection.connection(); + } catch (Throwable e) { + throw new Exception(e); + } + } + + /*destroy connection + * @see org.apache.commons.pool.PoolableObjectFactory#destroyObject(java.lang.Object) + */ + public void destroyObject(SnRpcConnection connection) throws Exception { + try { + connection.close(); + } catch (Throwable e) { + throw new Exception(e); + } + } + + /* make connection + * @see org.apache.commons.pool.PoolableObjectFactory#makeObject() + */ + public SnRpcConnection makeObject() throws Exception { + try { + return connectionFactory.getConnection(); + } catch (Throwable e) { + throw new Exception(e); + } + } + + /* passivateconnection + * @see org.apache.commons.pool.PoolableObjectFactory#passivateObject(java.lang.Object) + */ + public void passivateObject(SnRpcConnection connection) throws Exception { + } + + /* validate connection + * @see org.apache.commons.pool.PoolableObjectFactory#validateObject(java.lang.Object) + */ + public boolean validateObject(SnRpcConnection connection) { + return connection.isConnected() && !connection.isClosed(); + } + + public void setLifo(boolean lifo) { + pool.setLifo(lifo); + } + + public void setMaxActive(int maxActive) { + pool.setMaxActive(maxActive); + } + + public void setMaxIdle(int maxIdle) { + pool.setMaxIdle(maxIdle); + } + + public void setMaxWait(long maxWait) { + pool.setMaxWait(maxWait); + } + + public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { + pool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + } + + public void setMinIdle(int minIdle) { + pool.setMinIdle(minIdle); + } + + public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { + pool.setNumTestsPerEvictionRun(numTestsPerEvictionRun); + } + + public void setSoftMinEvictableIdleTimeMillis( + long softMinEvictableIdleTimeMillis) { + pool.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis); + } + + public void setTestOnBorrow(boolean testOnBorrow) { + pool.setTestOnBorrow(testOnBorrow); + } + + public void setTestOnReturn(boolean testOnReturn) { + pool.setTestOnReturn(testOnReturn); + } + + public void setTestWhileIdle(boolean testWhileIdle) { + pool.setTestWhileIdle(testWhileIdle); + } + + public void setTimeBetweenEvictionRunsMillis( + long timeBetweenEvictionRunsMillis) { + pool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + } + + public void setWhenExhaustedAction(byte whenExhaustedAction) { + pool.setWhenExhaustedAction(whenExhaustedAction); + } +} diff --git a/src/main/java/org/stefan/snrpc/client/SnNettyRpcConnection.java b/src/main/java/org/stefan/snrpc/client/SnNettyRpcConnection.java new file mode 100644 index 0000000..b6c38ab --- /dev/null +++ b/src/main/java/org/stefan/snrpc/client/SnNettyRpcConnection.java @@ -0,0 +1,172 @@ +package org.stefan.snrpc.client; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.bootstrap.ClientBootstrap; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFactory; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; +import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; +import org.jboss.netty.handler.codec.http.HttpChunkAggregator; +import org.jboss.netty.handler.codec.http.HttpContentCompressor; +import org.jboss.netty.handler.timeout.ReadTimeoutHandler; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.Timer; +import org.stefan.snrpc.SnRpcConnection; +import org.stefan.snrpc.conf.SnRpcConfig; +import org.stefan.snrpc.serializer.ProtobufSerializer; +import org.stefan.snrpc.serializer.SnRpcRequest; +import org.stefan.snrpc.serializer.SnRpcRequestEncoder; +import org.stefan.snrpc.serializer.SnRpcResponse; +import org.stefan.snrpc.serializer.SnRpcResponseDecoder; + +/** + * Sn netty rpc connection + * @author zhaoliangang 2014-11-13 + */ +public class SnNettyRpcConnection extends SimpleChannelHandler implements + SnRpcConnection { + + //inetsocket address + private InetSocketAddress inetAddr; + + //org.jboss.netty.channel.Channel + private volatile Channel channel; + + //response + private volatile SnRpcResponse response; + + //exception + private volatile Throwable exception; + + //HashedWheelTimer + private volatile Timer timer; + + private boolean connected; + + private SnRpcConfig snRpcConfig = SnRpcConfig.getInstance(); + + public SnNettyRpcConnection(String host, int port) { + snRpcConfig.loadProperties("snrpcserver.properties"); + this.inetAddr = new InetSocketAddress(host, port); + this.timer = new HashedWheelTimer(); + } + + public SnRpcResponse sendRequest(SnRpcRequest request) throws Throwable { + if (!isConnected()) { + throw new IllegalStateException("not connected"); + } + ChannelFuture writeFuture = channel.write(request); + if (!writeFuture.awaitUninterruptibly().isSuccess()) { + close(); + throw writeFuture.getCause(); + } + waitForResponse(); + + Throwable ex = exception; + SnRpcResponse resp = this.response; + this.response = null; + this.exception = null; + + if (null != ex) { + close(); + throw ex; + } + return resp; + } + + public void connection() throws Throwable { + if (connected) { + return; + } + ChannelFactory factory = new NioClientSocketChannelFactory( + Executors.newCachedThreadPool(), + Executors.newCachedThreadPool()); + ClientBootstrap bootstrap = new ClientBootstrap(factory); + + bootstrap.setOption("tcpNoDelay", Boolean.parseBoolean(snRpcConfig + .getProperty("snrpc.tcp.nodelay", "true"))); + bootstrap.setOption("reuseAddress", Boolean.parseBoolean(snRpcConfig + .getProperty("snrpc.tcp.reuseAddress", "true"))); + bootstrap.setPipelineFactory(new ChannelPipelineFactory() { + public ChannelPipeline getPipeline() { + ChannelPipeline pipeline = Channels.pipeline(); + int readTimeout = snRpcConfig.getReadTimeout(); + if (readTimeout > 0) { + pipeline.addLast("timeout", new ReadTimeoutHandler(timer, + readTimeout, TimeUnit.MILLISECONDS)); + } + pipeline.addLast("decoder", new SnRpcRequestEncoder( + ProtobufSerializer.getInstance())); + pipeline.addLast("aggregator", new HttpChunkAggregator(1024*1024)); + pipeline.addLast("encoder", new SnRpcResponseDecoder( + ProtobufSerializer.getInstance())); + pipeline.addLast("deflater", new HttpContentCompressor()); + pipeline.addLast("handler", SnNettyRpcConnection.this); + return pipeline; + } + }); + + ChannelFuture channelFuture = bootstrap.connect(inetAddr); + if (!channelFuture.awaitUninterruptibly().isSuccess()) { + bootstrap.releaseExternalResources(); + throw channelFuture.getCause(); + } + channel = channelFuture.getChannel(); + connected = true; + } + + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + response = (SnRpcResponse) e.getMessage(); + synchronized (channel) { + channel.notifyAll(); + } + } + + public void close() throws Throwable { + connected = false; + if (null != timer) { + timer.stop(); + timer = null; + } + if (null != channel) { + channel.close().awaitUninterruptibly(); + channel.getFactory().releaseExternalResources(); + + this.exception = new IOException("connection closed"); + synchronized (channel) { + channel.notifyAll(); + } + channel = null; + } + } + + public void waitForResponse() { + synchronized (channel) { + try { + channel.wait(); + } catch (InterruptedException e) { + } + } + } + + public boolean isConnected() { + return connected; + } + + public boolean isClosed() { + return (null == channel) || !channel.isConnected() + || !channel.isReadable() || !channel.isWritable(); + } + +} diff --git a/src/main/java/org/stefan/snrpc/client/SnNettyRpcConnectionFactory.java b/src/main/java/org/stefan/snrpc/client/SnNettyRpcConnectionFactory.java new file mode 100644 index 0000000..7a2b7ef --- /dev/null +++ b/src/main/java/org/stefan/snrpc/client/SnNettyRpcConnectionFactory.java @@ -0,0 +1,30 @@ +package org.stefan.snrpc.client; + +import java.net.InetSocketAddress; + +import org.stefan.snrpc.SnRpcConnection; +import org.stefan.snrpc.SnRpcConnectionFactory; + +/** + * SnNettyRpcConnectionFactory + * @author zhaoliangang 2014-11-13 + */ +public class SnNettyRpcConnectionFactory implements SnRpcConnectionFactory { + private InetSocketAddress serverAddr; + + public SnNettyRpcConnectionFactory(String host, int port) { + this.serverAddr = new InetSocketAddress(host, port); + } + + public SnRpcConnection getConnection() throws Throwable { + return new SnNettyRpcConnection(this.serverAddr.getHostName(), + this.serverAddr.getPort()); + } + + public void recycle(SnRpcConnection connection) throws Throwable { + if (null != connection) { + connection.close(); + } + } + +} diff --git a/src/main/java/org/stefan/snrpc/conf/ConfigureParse.java b/src/main/java/org/stefan/snrpc/conf/ConfigureParse.java new file mode 100644 index 0000000..dde5a0d --- /dev/null +++ b/src/main/java/org/stefan/snrpc/conf/ConfigureParse.java @@ -0,0 +1,12 @@ +package org.stefan.snrpc.conf; + +import java.util.List; + +/** + * ConfigureParse + * @author zhaoliangang 2014-11-12 + */ +public interface ConfigureParse { + + List parseService(); +} diff --git a/src/main/java/org/stefan/snrpc/conf/RpcImplementor.java b/src/main/java/org/stefan/snrpc/conf/RpcImplementor.java new file mode 100644 index 0000000..57bd93e --- /dev/null +++ b/src/main/java/org/stefan/snrpc/conf/RpcImplementor.java @@ -0,0 +1,62 @@ +package org.stefan.snrpc.conf; + +import java.io.Serializable; + +import com.esotericsoftware.reflectasm.MethodAccess; + +/** + * RpcImplementor + * @author zhaoliangang 2014-11-12 + */ +public class RpcImplementor implements Serializable { + + private static final long serialVersionUID = 4679847970989376057L; + + private Class processorClass; + + private MethodAccess methodAccess; + + public RpcImplementor() { + } + + /** + * @return the processorClass + */ + public Class getProcessorClass() { + return processorClass; + } + + /** + * @param processorClass + * @param methodAccess + */ + public RpcImplementor(Class processorClass) { + super(); + this.processorClass = processorClass; + this.methodAccess = MethodAccess.get(processorClass); + } + + /** + * @param processorClass + * the processorClass to set + */ + public void setProcessorClass(Class processorClass) { + this.processorClass = processorClass; + } + + /** + * @return the methodAccess + */ + public MethodAccess getMethodAccess() { + return methodAccess; + } + + /** + * @param methodAccess + * the methodAccess to set + */ + public void setMethodAccess(MethodAccess methodAccess) { + this.methodAccess = methodAccess; + } + +} diff --git a/src/main/java/org/stefan/snrpc/conf/RpcService.java b/src/main/java/org/stefan/snrpc/conf/RpcService.java new file mode 100644 index 0000000..851f66c --- /dev/null +++ b/src/main/java/org/stefan/snrpc/conf/RpcService.java @@ -0,0 +1,107 @@ +package org.stefan.snrpc.conf; + +/** + * RpcService + * + * + * + * + * + * + * @author zhaoliangang 2014-11-12 + */ +public class RpcService { + + protected Class typeClass; + protected String id; + protected String name; + private boolean overload = false; + private RpcImplementor rpcImplementor; + + /** + * @param id + * @param name + */ + public RpcService(String id, String name) { + super(); + this.id = id; + this.name = name; + } + + /** + * @return the typeClass + */ + public Class getTypeClass() { + return typeClass; + } + + /** + * @param typeClass + * the typeClass to set + */ + public void setTypeClass(Class typeClass) { + this.typeClass = typeClass; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the overload + */ + public boolean isOverload() { + return overload; + } + + /** + * @param overload + * the overload to set + */ + public void setOverload(boolean overload) { + this.overload = overload; + } + + /** + * @return the rpcImplementor + */ + public RpcImplementor getRpcImplementor() { + return rpcImplementor; + } + + /** + * @param rpcImplementor + * the rpcImplementor to set + */ + public void setRpcImplementor(RpcImplementor rpcImplementor) { + this.rpcImplementor = rpcImplementor; + } + +} diff --git a/src/main/java/org/stefan/snrpc/conf/SnRpcConfig.java b/src/main/java/org/stefan/snrpc/conf/SnRpcConfig.java new file mode 100644 index 0000000..98a19cf --- /dev/null +++ b/src/main/java/org/stefan/snrpc/conf/SnRpcConfig.java @@ -0,0 +1,105 @@ +package org.stefan.snrpc.conf; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.stefan.snrpc.exception.SnRpcException; +import org.stefan.snrpc.log.Logger; +import org.stefan.snrpc.log.LoggerFactory; +import org.stefan.snrpc.util.StringUtil; + +/** + * SnRpcConfig + * @author zhaoliangang 2014-11-13 + */ +public class SnRpcConfig { + + private static Logger logger = LoggerFactory.getLogger(SnRpcConfig.class); + + private static SnRpcConfig snRpcConfig; + + private static Properties properties = new Properties(); + + private SnRpcConfig() { + } + + public static SnRpcConfig getInstance() { + if (snRpcConfig == null) + snRpcConfig = new SnRpcConfig(); + return snRpcConfig; + } + + public void loadProperties(String fileName) { + if (StringUtil.isEmpty(fileName)) + throw new SnRpcException("snRpcConfig name is null..."); + InputStream inputStream = null; + try { + inputStream = Thread.currentThread().getContextClassLoader() + .getResourceAsStream(fileName); + properties.load(inputStream); + } catch (IOException e) { + throw new SnRpcException(" snRpcConfig file load failed... " + + fileName); + } finally { + try { + if (inputStream != null) + inputStream.close(); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } + if (properties == null) + throw new RuntimeException("Properties file loading failed: " + + fileName); + } + + public Properties getProperties() { + return properties; + } + + public String getProperty(String key) { + return properties.getProperty(key).trim(); + } + + public String getProperty(String key, String defaultValue) { + return properties.getProperty(key, defaultValue.trim()); + } + + /** + * get the service properties file,default is config.xml + * + * @return + */ + public String getpropertiesFile() { + String f = properties.getProperty("properties.file", "config.xml"); + return f.trim(); + } + + public boolean getDevMod() { + String dev = properties.getProperty("snrpc.dev", "false"); + return Boolean.parseBoolean(dev); + } + + /** + * get the method's invoke timeout,default is 3s + * + * @return + */ + public int getReadTimeout() { + String timeOutStr = properties + .getProperty("snrpc.read.timeout", "3000"); + return Integer.parseInt(timeOutStr); + } + + /** + * get the server's HTTP port,default is -1 + * + * @return + */ + public int getHttpPort() { + String port = properties.getProperty("snrpc.http.port", "-1"); + return Integer.parseInt(port); + } + +} diff --git a/src/main/java/org/stefan/snrpc/conf/XmlConfigureParse.java b/src/main/java/org/stefan/snrpc/conf/XmlConfigureParse.java new file mode 100644 index 0000000..36a4ecd --- /dev/null +++ b/src/main/java/org/stefan/snrpc/conf/XmlConfigureParse.java @@ -0,0 +1,150 @@ +package org.stefan.snrpc.conf; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.Node; +import org.dom4j.io.SAXReader; +import org.stefan.snrpc.log.Logger; +import org.stefan.snrpc.log.LoggerFactory; +import org.stefan.snrpc.util.StringUtil; + +/** + * + * XmlConfigureParse + * + + + + + + + * @author zhaoliangang 2014-11-12 + */ +public class XmlConfigureParse implements ConfigureParse { + + private static final Logger logger = LoggerFactory + .getLogger(XmlConfigureParse.class); + + private String configFile = null; + private Document document = null; + private Element root = null; + + /** + * @param configFile + * @param root + */ + public XmlConfigureParse(String configFile) { + super(); + this.configFile = configFile; + this.root = getRoot(); + } + + @SuppressWarnings("unchecked") + private Element getRoot() { + Document doc = getDocument(); + List list = doc.selectNodes("//application"); + if (list.size() > 0) { + Element aroot = list.get(0); + return aroot; + } + return null; + } + + private Document getDocument() { + InputStream is = getFileStream(); + try { + if (document == null) { + SAXReader sr = new SAXReader(); + sr.setValidation(false); + if (is == null) { + throw new RuntimeException("can not find config file..." + + configFile); + } + document = sr.read(is); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + throw new RuntimeException("get xml file failed"); + } finally { + if (is != null) + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return document; + } + + private InputStream getFileStream() { + return getFileStream(configFile); + } + + private InputStream getFileStream(String fileName) { + InputStream is = Thread.currentThread().getContextClassLoader() + .getResourceAsStream(fileName); + return is; + } + + @SuppressWarnings("unchecked") + public List parseService() { + + List slist = new ArrayList(); + Node serviceRoot = root.selectSingleNode("//rpcServices"); + List serviceList = serviceRoot.selectNodes("//rpcService"); + + int i = 0; + for (Element serviceNode : serviceList) { + String name = serviceNode.attributeValue("name");// service name + String interfaceStr = serviceNode.attributeValue("interface"); + String overloadStr = serviceNode.attributeValue("overload"); + + if (StringUtil.isEmpty(name)) { + logger.warn(configFile + ":a rpcservice's name is empty."); + continue; + } + if (StringUtil.isEmpty(interfaceStr)) { + logger.warn(configFile + ":rpcservice[" + name + + "] has an empty interface configure."); + continue; + } + Class type = null; + try { + type = Class.forName(interfaceStr); + } catch (ClassNotFoundException e) { + logger.error(e.getMessage()); + throw new RuntimeException("can't find rpc Interface:" + + interfaceStr); + } + RpcService service = new RpcService("" + i, name); + service.setTypeClass(type); + + if (StringUtil.isNotEmpty(overloadStr) + && "true".equals(overloadStr.trim())) { + service.setOverload(true); + } + + Element rpcImplementor = serviceNode.element("rpcImplementor"); + String processor = rpcImplementor.attributeValue("class"); + Class providerClass = null; + try { + providerClass = Class.forName(processor); + } catch (ClassNotFoundException e) { + logger.error(e.getMessage()); + throw new RuntimeException("can't find rpcImplementor Class:" + + processor); + } + RpcImplementor sv = new RpcImplementor(providerClass); + service.setRpcImplementor(sv); + slist.add(service); + i++; + } + return slist; + } + +} diff --git a/src/main/java/org/stefan/snrpc/exception/SerializerException.java b/src/main/java/org/stefan/snrpc/exception/SerializerException.java new file mode 100644 index 0000000..5dbf466 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/exception/SerializerException.java @@ -0,0 +1,28 @@ +package org.stefan.snrpc.exception; + +/** + * SerializerException + * + * @author zhaoliangang + * + */ +public class SerializerException extends RuntimeException { + + private static final long serialVersionUID = -6831220895401658422L; + + public SerializerException() { + super(); + } + + public SerializerException(String msg) { + super(msg); + } + + public SerializerException(Throwable t) { + super(t); + } + + public SerializerException(String msg, Throwable t) { + super(msg, t); + } +} diff --git a/src/main/java/org/stefan/snrpc/exception/SnRpcException.java b/src/main/java/org/stefan/snrpc/exception/SnRpcException.java new file mode 100644 index 0000000..ab464fe --- /dev/null +++ b/src/main/java/org/stefan/snrpc/exception/SnRpcException.java @@ -0,0 +1,28 @@ +package org.stefan.snrpc.exception; + +/** + * SnRpcException + * + * @author zhaoliangang + * + */ +public class SnRpcException extends RuntimeException { + + private static final long serialVersionUID = 6443147893553933129L; + + public SnRpcException() { + super(); + } + + public SnRpcException(String msg) { + super(msg); + } + + public SnRpcException(Throwable t) { + super(t); + } + + public SnRpcException(String msg, Throwable t) { + super(msg, t); + } +} diff --git a/src/main/java/org/stefan/snrpc/log/AbstractLogger.java b/src/main/java/org/stefan/snrpc/log/AbstractLogger.java new file mode 100644 index 0000000..42386c8 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/log/AbstractLogger.java @@ -0,0 +1,256 @@ +package org.stefan.snrpc.log; + +/** + * @author zhaoliangang 2014-11-12 + */ +public abstract class AbstractLogger implements Logger { + + private final String name; + + /** + * Instantiate the abstract logger. + */ + protected AbstractLogger(String nm) { + super(); + if (nm == null) { + throw new NullPointerException("Logger name may not be null."); + } + name = nm; + } + + /** + * Get the name of this logger. + */ + public String getName() { + return (name); + } + + /** + * Get the throwable from the last element of this array if it is Throwable, + * else null. + */ + public Throwable getThrowable(Object args[]) { + Throwable rv = null; + if (args.length > 0) { + if (args[args.length - 1] instanceof Throwable) { + rv = (Throwable) args[args.length - 1]; + } + } + return rv; + } + + /** + * True if debug is enabled for this logger. Default implementation always + * returns false + * + * @return true if debug messages would be displayed + */ + public abstract boolean isDebugEnabled(); + + /** + * True if debug is enabled for this logger. Default implementation always + * returns false + * + * @return true if info messages would be displayed + */ + public abstract boolean isInfoEnabled(); + + /** + * Log a message at debug level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + public void debug(Object message, Throwable exception) { + log(Level.DEBUG, message, exception); + } + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + public void debug(String message, Object... args) { + if (isDebugEnabled()) { + debug(String.format(message, args), getThrowable(args)); + } + } + + /** + * Log a message at debug level. + * + * @param message + * the message to log + */ + public void debug(Object message) { + debug(message, null); + } + + /** + * Log a message at info level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + public void info(Object message, Throwable exception) { + log(Level.INFO, message, exception); + } + + /** + * Log a formatted message at info level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + public void info(String message, Object... args) { + if (isInfoEnabled()) { + info(String.format(message, args), getThrowable(args)); + } + } + + /** + * Log a message at info level. + * + * @param message + * the message to log + */ + public void info(Object message) { + info(message, null); + } + + /** + * Log a message at warning level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + public void warn(Object message, Throwable exception) { + log(Level.WARN, message, exception); + } + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + public void warn(String message, Object... args) { + warn(String.format(message, args), getThrowable(args)); + } + + /** + * Log a message at warning level. + * + * @param message + * the message to log + */ + public void warn(Object message) { + warn(message, null); + } + + /** + * Log a message at error level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + public void error(Object message, Throwable exception) { + log(Level.ERROR, message, exception); + } + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + public void error(String message, Object... args) { + error(String.format(message, args), getThrowable(args)); + } + + /** + * Log a message at error level. + * + * @param message + * the message to log + */ + public void error(Object message) { + error(message, null); + } + + /** + * Log a message at fatal level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + public void fatal(Object message, Throwable exception) { + log(Level.FATAL, message, exception); + } + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + public void fatal(String message, Object... args) { + fatal(String.format(message, args), getThrowable(args)); + } + + /** + * Log a message at fatal level. + * + * @param message + * the message to log + */ + public void fatal(Object message) { + fatal(message, null); + } + + /** + * Log a message at the given level. + * + * @param level + * the level + * @param message + * the message + */ + public void log(Level level, Object message) { + log(level, message, null); + } + + /** + * Subclasses should implement this method to determine what to do when a + * client wants to log at a particular level. + * + * @param level + * the level to log at (see the fields of this class) + * @param message + * the message to log + * @param e + * the exception that caused the message (or null) + */ + public abstract void log(Level level, Object message, Throwable e); +} diff --git a/src/main/java/org/stefan/snrpc/log/DefaultLogger.java b/src/main/java/org/stefan/snrpc/log/DefaultLogger.java new file mode 100644 index 0000000..85a0dc5 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/log/DefaultLogger.java @@ -0,0 +1,52 @@ +package org.stefan.snrpc.log; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author zhaoliangang 2014-11-12 + */ +public class DefaultLogger extends AbstractLogger { + + private final SimpleDateFormat df; + + /** + * Get an instance of DefaultLogger. + */ + public DefaultLogger(String name) { + super(name); + df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + } + + /** + * False. + */ + @Override + public boolean isDebugEnabled() { + return (false); + } + + /** + * True. + */ + @Override + public boolean isInfoEnabled() { + return (true); + } + + /** + * @see AbstractLogger + */ + @Override + public synchronized void log(Level level, Object message, Throwable e) { + if (level == Level.INFO || level == Level.WARN || level == Level.ERROR + || level == Level.FATAL) { + System.err.printf("%s %s %s: %s\n", df.format(new Date()), + level.name(), getName(), message); + if (e != null) { + e.printStackTrace(); + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/stefan/snrpc/log/Level.java b/src/main/java/org/stefan/snrpc/log/Level.java new file mode 100644 index 0000000..e689b70 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/log/Level.java @@ -0,0 +1,18 @@ +package org.stefan.snrpc.log; + +/** + * log level + * + * @author zhaoliangang + * + */ +public enum Level { + + DEBUG, INFO, WARN, ERROR, FATAL; + + @Override + public String toString() { + return "{LogLevel:" + name() + "}"; + } + +} diff --git a/src/main/java/org/stefan/snrpc/log/Log4JLogger.java b/src/main/java/org/stefan/snrpc/log/Log4JLogger.java new file mode 100644 index 0000000..522a1b3 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/log/Log4JLogger.java @@ -0,0 +1,80 @@ +package org.stefan.snrpc.log; + +/** + * @author zhaoliangang 2014-11-12 + */ +public class Log4JLogger extends AbstractLogger { + + // Can't really import this without confusion as there's another thing + // by this name in here. + private final org.apache.log4j.Logger l4jLogger; + + /** + * Get an instance of Log4JLogger. + */ + public Log4JLogger(String name) { + super(name); + + // Get the log4j logger instance. + l4jLogger = org.apache.log4j.Logger.getLogger(name); + } + + /** + * True if the underlying logger would allow debug messages through. + */ + @Override + public boolean isDebugEnabled() { + return (l4jLogger.isDebugEnabled()); + } + + /** + * True if the underlying logger would allow info messages through. + */ + @Override + public boolean isInfoEnabled() { + return (l4jLogger.isInfoEnabled()); + } + + /** + * Wrapper around log4j. + * + * @param level + * net.spy.compat.log.AbstractLogger level. + * @param message + * object message + * @param e + * optional throwable + */ + @Override + public void log(Level level, Object message, Throwable e) { + org.apache.log4j.Level pLevel = org.apache.log4j.Level.DEBUG; + + switch (level == null ? Level.FATAL : level) { + case DEBUG: + pLevel = org.apache.log4j.Level.DEBUG; + break; + case INFO: + pLevel = org.apache.log4j.Level.INFO; + break; + case WARN: + pLevel = org.apache.log4j.Level.WARN; + break; + case ERROR: + pLevel = org.apache.log4j.Level.ERROR; + break; + case FATAL: + pLevel = org.apache.log4j.Level.FATAL; + break; + default: + // I don't know what this is, so consider it fatal + pLevel = org.apache.log4j.Level.FATAL; + l4jLogger.log("org.stefan.snrpc.log.AbstractLogger", pLevel, + "Unhandled log level: " + level + + " for the following message", null); + } + + l4jLogger + .log("org.stefan.snrpc.log.AbstractLogger", pLevel, message, e); + } + +} diff --git a/src/main/java/org/stefan/snrpc/log/Logger.java b/src/main/java/org/stefan/snrpc/log/Logger.java new file mode 100644 index 0000000..a09bf49 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/log/Logger.java @@ -0,0 +1,189 @@ +package org.stefan.snrpc.log; + +/** + * @author zhaoliangang + * + */ +public interface Logger { + + /** + * Get the name of this logger. + */ + String getName(); + + /** + * True if debug is enabled for this logger. + * + * @return true if debug messages would be displayed + */ + boolean isDebugEnabled(); + + /** + * True if info is enabled for this logger. + * + * @return true if info messages would be displayed + */ + boolean isInfoEnabled(); + + /** + * Log a message at the specified level. + * + * @param level + * the level at which to log + * @param message + * the message to log + * @param exception + * an exception that caused the message + */ + void log(Level level, Object message, Throwable exception); + + /** + * Log a message at the specified level. + * + * @param level + * the level at which to log + * @param message + * the message to log + */ + void log(Level level, Object message); + + /** + * Log a message at debug level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + void debug(Object message, Throwable exception); + + /** + * Log a message at debug level. + * + * @param message + * the message to log + */ + void debug(Object message); + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + void debug(String message, Object... args); + + /** + * Log a message at info level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + void info(Object message, Throwable exception); + + /** + * Log a message at info level. + * + * @param message + * the message to log + */ + void info(Object message); + + /** + * Log a formatted message at info level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + void info(String message, Object... args); + + /** + * Log a message at warning level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + void warn(Object message, Throwable exception); + + /** + * Log a message at warning level. + * + * @param message + * the message to log + */ + void warn(Object message); + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + void warn(String message, Object... args); + + /** + * Log a message at error level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + void error(Object message, Throwable exception); + + /** + * Log a message at error level. + * + * @param message + * the message to log + */ + void error(Object message); + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + void error(String message, Object... args); + + /** + * Log a message at fatal level. + * + * @param message + * the message to log + * @param exception + * the exception that caused the message to be generated + */ + void fatal(Object message, Throwable exception); + + /** + * Log a message at fatal level. + * + * @param message + * the message to log + */ + void fatal(Object message); + + /** + * Log a formatted message at debug level. + * + * @param message + * the message to log + * @param args + * the arguments for that message + */ + void fatal(String message, Object... args); +} diff --git a/src/main/java/org/stefan/snrpc/log/LoggerFactory.java b/src/main/java/org/stefan/snrpc/log/LoggerFactory.java new file mode 100644 index 0000000..5a017e4 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/log/LoggerFactory.java @@ -0,0 +1,125 @@ +package org.stefan.snrpc.log; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author zhaoliangang 2014-11-12 + */ +public class LoggerFactory { + + private static LoggerFactory instance = null; + private final ConcurrentMap instances; + private Constructor instanceConstructor; + + private LoggerFactory() { + super(); + instances = new ConcurrentHashMap(); + } + + private static void init() { + if (instance == null) + instance = new LoggerFactory(); + } + + public static Logger getLogger(Class clazz) { + return getLogger(clazz.getName()); + } + + public static Logger getLogger(String name) { + if (name == null) + throw new NullPointerException("Logger name can not be null..."); + + init(); + return instance.internalGetLogger(name); + } + + private Logger internalGetLogger(String name) { + assert name != null : "logger name is null"; + Logger logger = instances.get(name); + if (logger == null) { + Logger newLogger = null; + try { + newLogger = getNewInstance(name); + } catch (Exception e) { + throw new RuntimeException("Problem getting logger", e); + } + Logger tmp = instances.putIfAbsent(name, newLogger); + logger = tmp == null ? newLogger : tmp; + } + + return logger; + } + + /** + * @param name + * @return + */ + private Logger getNewInstance(String name) throws InstantiationException, + IllegalAccessException, IllegalArgumentException, + InvocationTargetException { + if (instanceConstructor == null) { + getConstructor(); + } + Object[] args = { name }; + Logger logger = instanceConstructor.newInstance(args); + return logger; + } + + // Find the appropriate constructor + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void getConstructor() { + Class c = DefaultLogger.class; + String className = System.getProperty("org.stefan.log.LoggerImpl"); + + if (className != null) { + try { + c = (Class) Class.forName(className); + } catch (NoClassDefFoundError e) { + System.err.println("Warning: " + className + + " not found while initializing" + + " org.stefan.snrpc.log.LoggerFactory"); + e.printStackTrace(); + c = DefaultLogger.class; + } catch (ClassNotFoundException e) { + System.err.println("Warning: " + className + + " not found while initializing" + + " org.stefan.snrpc.log.LoggerFactory"); + e.printStackTrace(); + c = DefaultLogger.class; + } + } + + // Find the best constructor + try { + // Try to find a constructor that takes a single string + Class[] args = { String.class }; + instanceConstructor = c.getConstructor(args); + } catch (NoSuchMethodException e) { + try { + // Try to find an empty constructor + Class[] args = {}; + instanceConstructor = c.getConstructor(args); + } catch (NoSuchMethodException e2) { + System.err.println("Warning: " + className + + " has no appropriate constructor, using defaults."); + + // Try to find a constructor that takes a single string + try { + Class[] args = { String.class }; + instanceConstructor = DefaultLogger.class + .getConstructor(args); + } catch (NoSuchMethodException e3) { + // This shouldn't happen. + throw new NoSuchMethodError( + "There used to be a constructor that takes a single " + + "String on " + DefaultLogger.class + + ", but I can't " + "find one now."); + } // SOL + } // No empty constructor + } // No constructor that takes a string + } // getConstructor + +} diff --git a/src/main/java/org/stefan/snrpc/log/SunLogger.java b/src/main/java/org/stefan/snrpc/log/SunLogger.java new file mode 100644 index 0000000..c25e1cf --- /dev/null +++ b/src/main/java/org/stefan/snrpc/log/SunLogger.java @@ -0,0 +1,111 @@ +package org.stefan.snrpc.log; + +/** + * @author zhaoliangang 2014-11-14 + */ +public class SunLogger extends AbstractLogger { + + // Can't really import this without confusion as there's another thing + // by this name in here. + private final java.util.logging.Logger sunLogger; + + /** + * Get an instance of SunLogger. + */ + public SunLogger(String name) { + super(name); + + // Get the sun logger instance. + sunLogger = java.util.logging.Logger.getLogger(name); + } + + /** + * True if the underlying logger would allow Level.FINE through. + */ + @Override + public boolean isDebugEnabled() { + return (sunLogger.isLoggable(java.util.logging.Level.FINE)); + } + + /** + * True if the underlying logger would allow Level.INFO through. + */ + @Override + public boolean isInfoEnabled() { + return (sunLogger.isLoggable(java.util.logging.Level.INFO)); + } + + /** + * Wrapper around sun logger. + * + * @param level + * net.spy.compat.log.AbstractLogger level. + * @param message + * object message + * @param e + * optional throwable + */ + @Override + public void log(Level level, Object message, Throwable e) { + java.util.logging.Level sLevel = java.util.logging.Level.SEVERE; + + switch (level == null ? Level.FATAL : level) { + case DEBUG: + sLevel = java.util.logging.Level.FINE; + break; + case INFO: + sLevel = java.util.logging.Level.INFO; + break; + case WARN: + sLevel = java.util.logging.Level.WARNING; + break; + case ERROR: + sLevel = java.util.logging.Level.SEVERE; + break; + case FATAL: + sLevel = java.util.logging.Level.SEVERE; + break; + default: + // I don't know what this is, so consider it fatal + sLevel = java.util.logging.Level.SEVERE; + sunLogger.log(sLevel, "Unhandled log level: " + level + + " for the following message"); + } + + // Figure out who was logging. + Throwable t = new Throwable(); + StackTraceElement[] ste = t.getStackTrace(); + StackTraceElement logRequestor = null; + String alclass = AbstractLogger.class.getName(); + for (int i = 0; i < ste.length && logRequestor == null; i++) { + if (ste[i].getClassName().equals(alclass)) { + // Make sure there's another stack frame. + if (i + 1 < ste.length) { + logRequestor = ste[i + 1]; + if (logRequestor.getClassName().equals(alclass)) { + logRequestor = null; + } // Also AbstractLogger + } // Found something that wasn't abstract logger + } // check for abstract logger + } + + // See if we could figure out who was doing the original logging, + // if we could, we want to include a useful class and method name + if (logRequestor != null) { + if (e != null) { + sunLogger.logp(sLevel, logRequestor.getClassName(), + logRequestor.getMethodName(), message.toString(), e); + } else { + sunLogger.logp(sLevel, logRequestor.getClassName(), + logRequestor.getMethodName(), message.toString()); + } + } else { + if (e != null) { + sunLogger.log(sLevel, message.toString(), e); + } else { + sunLogger.log(sLevel, message.toString()); + } + } + } + +} diff --git a/src/main/java/org/stefan/snrpc/serializer/AbstractProtostuffSerializer.java b/src/main/java/org/stefan/snrpc/serializer/AbstractProtostuffSerializer.java new file mode 100644 index 0000000..dab0d4f --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/AbstractProtostuffSerializer.java @@ -0,0 +1,90 @@ +package org.stefan.snrpc.serializer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.stefan.snrpc.exception.SerializerException; +import org.stefan.snrpc.util.BufferCache; +import org.stefan.snrpc.util.IOUtils; +import org.stefan.snrpc.util.SchemaCache; + +import com.dyuproject.protostuff.LinkedBuffer; +import com.dyuproject.protostuff.Schema; + +/** + * AbstractProtostuffSerializer + * @author zhaoliangang 2014-11-14 + */ +public abstract class AbstractProtostuffSerializer implements ClientSerializer, + ServerSerializer { + /** + * @param buffer + * buffer writen to + * @param object + * @param schema + * @return length + */ + protected abstract int writeObject(LinkedBuffer buffer, T object, + Schema schema); + + /** + * @param bytes + * @param template + * @param schema + * @return + */ + protected abstract void parseObject(byte[] bytes, T template, + Schema schema); + + public SnRpcRequest decodeRequest(InputStream inputStream) + throws SerializerException, IOException { + return decode(inputStream, new SnRpcRequest()); + } + + public void encodeResponse(OutputStream outputStream, SnRpcResponse result) + throws SerializerException, IOException { + encode(outputStream, result); + } + + public SnRpcResponse decodeResponse(InputStream inputStream) + throws SerializerException, IOException { + return decode(inputStream, new SnRpcResponse()); + } + + public void encodeRequest(OutputStream outputStream, SnRpcRequest request) + throws SerializerException, IOException { + encode(outputStream, request); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void encode(OutputStream out, T object) throws IOException { + LinkedBuffer buffer = BufferCache.getBuffer(); + Schema schema = null; + if (null == object) { + schema = SchemaCache.getSchema(Object.class); + } else { + schema = SchemaCache.getSchema(object.getClass()); + } + + // write the length header + int length = writeObject(buffer, object, schema); + IOUtils.writeInt(out, length); + // write content + LinkedBuffer.writeTo(out, buffer); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private T decode(InputStream in, T template) throws IOException { + Schema schema = SchemaCache.getSchema(template.getClass()); + + // read the length header + int length = IOUtils.readInt(in); + // read exactly $length bytes + byte[] bytes = new byte[length]; + IOUtils.readFully(in, bytes, 0, length); + // parse object + parseObject(bytes, template, schema); + return template; + } +} diff --git a/src/main/java/org/stefan/snrpc/serializer/ClientSerializer.java b/src/main/java/org/stefan/snrpc/serializer/ClientSerializer.java new file mode 100644 index 0000000..4f58532 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/ClientSerializer.java @@ -0,0 +1,37 @@ +package org.stefan.snrpc.serializer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.stefan.snrpc.exception.SerializerException; + +/** + * ClientSerializer + * @author zhaoliangang 2014-11-13 + */ +public interface ClientSerializer { + /** + * deserialize the inputStream + * + * @param inputStream + * @return + * @throws SerializeException + * @throws IOException + */ + SnRpcResponse decodeResponse(InputStream inputStream) + throws SerializerException, IOException; + + /** + * serialize the request object into the outputStream + * + * @param outputStream + * @param object + * @param method + * @param arguments + * @throws SerializeException + * @throws IOException + */ + void encodeRequest(OutputStream outputStream, SnRpcRequest request) + throws SerializerException, IOException; +} \ No newline at end of file diff --git a/src/main/java/org/stefan/snrpc/serializer/ProtobufSerializer.java b/src/main/java/org/stefan/snrpc/serializer/ProtobufSerializer.java new file mode 100644 index 0000000..66f8f43 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/ProtobufSerializer.java @@ -0,0 +1,32 @@ +package org.stefan.snrpc.serializer; + +import com.dyuproject.protostuff.LinkedBuffer; +import com.dyuproject.protostuff.ProtobufIOUtil; +import com.dyuproject.protostuff.Schema; + +/** + * ProtobufSerializer + * @author zhaoliangang 2014-11-14 + */ +public class ProtobufSerializer extends AbstractProtostuffSerializer { + + private static final ProtobufSerializer INSTANCE = new ProtobufSerializer(); + + private ProtobufSerializer() { + } + + public static ProtobufSerializer getInstance() { + return INSTANCE; + } + + @Override + protected int writeObject(LinkedBuffer buffer, T object, + Schema schema) { + return ProtobufIOUtil.writeTo(buffer, object, schema); + } + + @Override + protected void parseObject(byte[] bytes, T template, Schema schema) { + ProtobufIOUtil.mergeFrom(bytes, template, schema); + } +} diff --git a/src/main/java/org/stefan/snrpc/serializer/ServerSerializer.java b/src/main/java/org/stefan/snrpc/serializer/ServerSerializer.java new file mode 100644 index 0000000..c5eae09 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/ServerSerializer.java @@ -0,0 +1,35 @@ +package org.stefan.snrpc.serializer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.stefan.snrpc.exception.SerializerException; + +/** + * ServerSerializer + * @author zhaoliangang 2014-11-13 + */ +public interface ServerSerializer { + /** + * deserialize the inputStream + * + * @param inputStream + * @return + * @throws SerializeException + * @throws IOException + */ + SnRpcRequest decodeRequest(InputStream inputStream) + throws SerializerException, IOException; + + /** + * serialize the result object into the outputStream + * + * @param outputStream + * @param result + * @throws SerializeException + * @throws IOException + */ + void encodeResponse(OutputStream outputStream, SnRpcResponse result) + throws SerializerException, IOException; +} diff --git a/src/main/java/org/stefan/snrpc/serializer/SnRpcRequest.java b/src/main/java/org/stefan/snrpc/serializer/SnRpcRequest.java new file mode 100644 index 0000000..ef589ab --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/SnRpcRequest.java @@ -0,0 +1,88 @@ +package org.stefan.snrpc.serializer; + +import org.stefan.snrpc.util.MessageFormatter; + +/** + * SnRpcRequest + * @author zhaoliangang 2014-11-13 + */ +public class SnRpcRequest { + + private String requestID; + + private String className; + + private String methodName; + + private String[] parameterTypes; + + private Object[] parameters; + + public SnRpcRequest() { + } + + public SnRpcRequest(String className, String methodName, + String[] parameterTypes, Object[] parameters) { + this.className = className; + this.methodName = methodName; + this.parameterTypes = parameterTypes; + this.parameters = parameters; + } + + public SnRpcRequest(String requestID, String className, String methodName, + String[] parameterTypes, Object[] parameters) { + this.requestID = requestID; + this.className = className; + this.methodName = methodName; + this.parameterTypes = parameterTypes; + this.parameters = parameters; + } + + public String getRequestID() { + return requestID; + } + + public void setRequestID(String requestID) { + this.requestID = requestID; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getMethodName() { + return methodName; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public String[] getParameterTypes() { + return parameterTypes; + } + + public void setParameterTypes(String[] parameterTypes) { + this.parameterTypes = parameterTypes; + } + + public Object[] getParameters() { + return parameters; + } + + public void setParameters(Object[] parameters) { + this.parameters = parameters; + } + + @Override + public String toString() { + return MessageFormatter + .format("requestID: {}, className: {}, methodName: {}, parameterTypes: {}, parameters: {}", + new Object[] { requestID, className, methodName, + parameterTypes, parameters }); + } +} diff --git a/src/main/java/org/stefan/snrpc/serializer/SnRpcRequestDecoder.java b/src/main/java/org/stefan/snrpc/serializer/SnRpcRequestDecoder.java new file mode 100644 index 0000000..17253b9 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/SnRpcRequestDecoder.java @@ -0,0 +1,37 @@ +package org.stefan.snrpc.serializer; + +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.FrameDecoder; + +/** + * SnRpcRequestDecoder + * + * @author zhaoliangang 2014-11-13 + */ +public class SnRpcRequestDecoder extends FrameDecoder { + + private final ServerSerializer serializer; + + public SnRpcRequestDecoder(ServerSerializer serializer) { + this.serializer = serializer; + } + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + ChannelBuffer buffer) throws Exception { + if (buffer.readableBytes() < 4) { + return null; + } + int length = buffer.getInt(buffer.readerIndex()); + if (buffer.readableBytes() < length + 4) { + return null; + } + ChannelBufferInputStream in = new ChannelBufferInputStream(buffer); + SnRpcRequest request = serializer.decodeRequest(in); + return request; + } + +} diff --git a/src/main/java/org/stefan/snrpc/serializer/SnRpcRequestEncoder.java b/src/main/java/org/stefan/snrpc/serializer/SnRpcRequestEncoder.java new file mode 100644 index 0000000..a9f69d6 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/SnRpcRequestEncoder.java @@ -0,0 +1,33 @@ +package org.stefan.snrpc.serializer; + +import java.io.ByteArrayOutputStream; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; + +/** + * @author zhaoliangang 2014-11-13 + */ +public class SnRpcRequestEncoder extends SimpleChannelHandler { + + private final ClientSerializer serializer; + + public SnRpcRequestEncoder(ClientSerializer serializer) { + this.serializer = serializer; + } + + @Override + public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + SnRpcRequest request = (SnRpcRequest) e.getMessage(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(16384); + serializer.encodeRequest(baos, request); + ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(baos.toByteArray()); + Channels.write(ctx, e.getFuture(), buffer); + } + +} diff --git a/src/main/java/org/stefan/snrpc/serializer/SnRpcResponse.java b/src/main/java/org/stefan/snrpc/serializer/SnRpcResponse.java new file mode 100644 index 0000000..f3d646a --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/SnRpcResponse.java @@ -0,0 +1,55 @@ +package org.stefan.snrpc.serializer; + +import org.stefan.snrpc.util.MessageFormatter; + +/** + * SnRpcResponse + * + * @author zhaoliangang 2014-11-13 + */ +public class SnRpcResponse { + + private String requestID; + + private Throwable exception; + + private Object result; + + public SnRpcResponse() { + } + + public SnRpcResponse(String requestID) { + this.requestID = requestID; + } + + public String getRequestID() { + return requestID; + } + + public void setRequestID(String requestID) { + this.requestID = requestID; + } + + public Throwable getException() { + return exception; + } + + public void setException(Throwable exception) { + this.exception = exception; + } + + public Object getResult() { + return result; + } + + public void setResult(Object result) { + this.result = result; + } + + @Override + public String toString() { + return MessageFormatter.format( + "requestID: {}, result: {}, exception: {}", new Object[] { + requestID, result, exception }); + } +} diff --git a/src/main/java/org/stefan/snrpc/serializer/SnRpcResponseDecoder.java b/src/main/java/org/stefan/snrpc/serializer/SnRpcResponseDecoder.java new file mode 100644 index 0000000..7ebaae4 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/SnRpcResponseDecoder.java @@ -0,0 +1,35 @@ +package org.stefan.snrpc.serializer; + +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.FrameDecoder; + +/** + * SnRpcResponseDecoder + * @author zhaoliangang 2014-11-13 + */ +public class SnRpcResponseDecoder extends FrameDecoder { + + private final ClientSerializer serializer; + + public SnRpcResponseDecoder(ClientSerializer serializer) { + this.serializer = serializer; + } + + @Override + protected Object decode(ChannelHandlerContext context, Channel channel, + ChannelBuffer buffer) throws Exception { + if (buffer.readableBytes() < 4) { + return null; + } + int length = buffer.getInt(buffer.readerIndex()); + if (buffer.readableBytes() < length + 4) { + return null; + } + ChannelBufferInputStream in = new ChannelBufferInputStream(buffer); + SnRpcResponse response = serializer.decodeResponse(in); + return response; + } +} diff --git a/src/main/java/org/stefan/snrpc/serializer/SnRpcResponseEncoder.java b/src/main/java/org/stefan/snrpc/serializer/SnRpcResponseEncoder.java new file mode 100644 index 0000000..7a110ce --- /dev/null +++ b/src/main/java/org/stefan/snrpc/serializer/SnRpcResponseEncoder.java @@ -0,0 +1,32 @@ +package org.stefan.snrpc.serializer; + +import java.io.ByteArrayOutputStream; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; + +/** + * SnRpcResponseEncoder + * @author zhaoliangang 2014-11-13 + */ +public class SnRpcResponseEncoder extends SimpleChannelHandler { + private final ServerSerializer serializer; + + public SnRpcResponseEncoder(ServerSerializer serializer) { + this.serializer = serializer; + } + + @Override + public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + SnRpcResponse response = (SnRpcResponse) e.getMessage(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(16384); + serializer.encodeResponse(baos, response); + ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(baos.toByteArray()); + Channels.write(ctx, e.getFuture(), buffer); + } +} diff --git a/src/main/java/org/stefan/snrpc/server/ParseXmlToService.java b/src/main/java/org/stefan/snrpc/server/ParseXmlToService.java new file mode 100644 index 0000000..00de01b --- /dev/null +++ b/src/main/java/org/stefan/snrpc/server/ParseXmlToService.java @@ -0,0 +1,25 @@ +package org.stefan.snrpc.server; + +import java.util.List; + +import org.stefan.snrpc.conf.ConfigureParse; +import org.stefan.snrpc.conf.RpcService; +import org.stefan.snrpc.conf.SnRpcConfig; +import org.stefan.snrpc.conf.XmlConfigureParse; + +/** + * ParseXmlToService + * + * @author zhaoliangang 2014-11-14 + */ +public class ParseXmlToService { + + public void parse() { + String configFile = SnRpcConfig.getInstance().getpropertiesFile(); + ConfigureParse parse = new XmlConfigureParse(configFile); + List serviceList = parse.parseService(); + for (RpcService service : serviceList) { + SnNettyRpcServerHandler.putService(service); + } + } +} diff --git a/src/main/java/org/stefan/snrpc/server/SnNettyRpcServer.java b/src/main/java/org/stefan/snrpc/server/SnNettyRpcServer.java new file mode 100644 index 0000000..f6be170 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/server/SnNettyRpcServer.java @@ -0,0 +1,179 @@ +package org.stefan.snrpc.server; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.group.ChannelGroup; +import org.jboss.netty.channel.group.ChannelGroupFuture; +import org.jboss.netty.channel.group.DefaultChannelGroup; +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; +import org.jboss.netty.handler.codec.http.HttpChunkAggregator; +import org.jboss.netty.handler.codec.http.HttpContentCompressor; +import org.jboss.netty.handler.timeout.ReadTimeoutHandler; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.Timer; +import org.stefan.snrpc.SnRpcServer; +import org.stefan.snrpc.conf.SnRpcConfig; +import org.stefan.snrpc.log.Logger; +import org.stefan.snrpc.log.LoggerFactory; +import org.stefan.snrpc.serializer.ProtobufSerializer; +import org.stefan.snrpc.serializer.SnRpcRequestDecoder; +import org.stefan.snrpc.serializer.SnRpcResponseEncoder; +import org.stefan.snrpc.util.HandlerMapper; + +/** + * + * SnNettyRpcServer + * + * @author zhaoliangang 2014-11-13 + */ +public class SnNettyRpcServer implements SnRpcServer { + + private static Logger logger = LoggerFactory + .getLogger(SnNettyRpcServer.class); + + protected Map handlersMap; + + private ServerBootstrap bootstrap = null; + private AtomicBoolean stopped = new AtomicBoolean(false); + private SnRpcConfig snRpcConfig = SnRpcConfig.getInstance(); + private Timer timer; + private int httpListenPort; + + public SnNettyRpcServer(Object... handlers) { + snRpcConfig.loadProperties("snrpcserver.properties"); + this.handlersMap = HandlerMapper.getHandlerMap(handlers); + } + + public SnNettyRpcServer(String fileName, Object... handlers) { + snRpcConfig.loadProperties(fileName); + this.handlersMap = HandlerMapper.getHandlerMap(handlers); + } + + private void initServerInfo() { + httpListenPort = snRpcConfig.getHttpPort(); + new ParseXmlToService().parse(); + } + + private void initHttpBootstrap() { + if (SnRpcConfig.getInstance().getDevMod()) { + StatisticsService.reportPerformance(); + } + logger.info("init HTTP Bootstrap..........."); + final ChannelGroup channelGroup = new DefaultChannelGroup(getClass() + .getName()); + bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(), + Executors.newCachedThreadPool())); + + bootstrap.setOption("tcpNoDelay", Boolean.parseBoolean(snRpcConfig + .getProperty("snrpc.tcp.nodelay", "true"))); + bootstrap.setOption("reuseAddress", Boolean.parseBoolean(snRpcConfig + .getProperty("snrpc.tcp.reuseaddress", "true"))); + + timer = new HashedWheelTimer(); + bootstrap.setPipelineFactory(new ChannelPipelineFactory() { + public ChannelPipeline getPipeline() throws Exception { + ChannelPipeline pipeline = Channels.pipeline(); + + int readTimeout = snRpcConfig.getReadTimeout(); + if (readTimeout > 0) { + pipeline.addLast("timeout", new ReadTimeoutHandler(timer, + readTimeout, TimeUnit.MILLISECONDS)); + } + + pipeline.addLast("decoder", new SnRpcRequestDecoder( + ProtobufSerializer.getInstance())); + pipeline.addLast("aggregator", new HttpChunkAggregator(1048576)); + pipeline.addLast("encoder", new SnRpcResponseEncoder( + ProtobufSerializer.getInstance())); + pipeline.addLast("deflater", new HttpContentCompressor()); + pipeline.addLast("handler", new SnNettyRpcServerHandler( + handlersMap, channelGroup)); + return pipeline; + } + }); + + if (!checkPortConfig(httpListenPort)) { + throw new IllegalStateException("port: " + httpListenPort + + " already in use!"); + } + + Channel channel = bootstrap.bind(new InetSocketAddress(httpListenPort)); + channelGroup.add(channel); + logger.info("snrpc server started"); + + waitForShutdownCommand(); + ChannelGroupFuture future = channelGroup.close(); + future.awaitUninterruptibly(); + bootstrap.releaseExternalResources(); + timer.stop(); + timer = null; + + logger.info("snrpc server stoped"); + + } + + public void start() { + initServerInfo(); + initHttpBootstrap(); + } + + public void stop() throws Throwable { + stopped.set(true); + synchronized (stopped) { + stopped.notifyAll(); + } + } + + private void waitForShutdownCommand() { + synchronized (stopped) { + while (!stopped.get()) { + try { + stopped.wait(); + } catch (InterruptedException e) { + } + } + } + } + + private boolean checkPortConfig(int listenPort) { + if (listenPort < 0 || listenPort > 65536) { + throw new IllegalArgumentException("Invalid start port: " + + listenPort); + } + ServerSocket ss = null; + DatagramSocket ds = null; + try { + ss = new ServerSocket(listenPort); + ss.setReuseAddress(true); + ds = new DatagramSocket(listenPort); + ds.setReuseAddress(true); + return true; + } catch (IOException e) { + } finally { + if (ds != null) { + ds.close(); + } + if (ss != null) { + try { + ss.close(); + } catch (IOException e) { + } + } + } + return false; + } + +} diff --git a/src/main/java/org/stefan/snrpc/server/SnNettyRpcServerHandler.java b/src/main/java/org/stefan/snrpc/server/SnNettyRpcServerHandler.java new file mode 100644 index 0000000..93ae0c3 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/server/SnNettyRpcServerHandler.java @@ -0,0 +1,123 @@ +package org.stefan.snrpc.server; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +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.channel.group.ChannelGroup; +import org.stefan.snrpc.conf.RpcService; +import org.stefan.snrpc.conf.SnRpcConfig; +import org.stefan.snrpc.log.Logger; +import org.stefan.snrpc.log.LoggerFactory; +import org.stefan.snrpc.serializer.SnRpcRequest; +import org.stefan.snrpc.serializer.SnRpcResponse; +import org.stefan.snrpc.util.ReflectionCache; + +/** + * SnNettyRpcServerHandler + * + * @author zhaoliangang 2014-11-13 + */ +public class SnNettyRpcServerHandler extends SimpleChannelUpstreamHandler { + + private static final Logger logger = LoggerFactory + .getLogger(SnNettyRpcServerHandler.class); + + private final Map handlersMap; + + private final static Map serviceMap = new HashMap(); + + private final ChannelGroup channelGroups; + + public SnNettyRpcServerHandler(Map handlersMap) { + this(handlersMap, null); + } + + public SnNettyRpcServerHandler(Map handlersMap, + ChannelGroup channelGroups) { + this.handlersMap = handlersMap; + this.channelGroups = channelGroups; + } + + public static void putService(RpcService service) { + if (null != service) { + serviceMap.put(service.getName(), service); + } + } + + public static Map getServiceMap() { + return Collections.unmodifiableMap(serviceMap); + } + + public static RpcService getServiceByName(String serviceName) { + return serviceMap.get(serviceName); + } + + @Override + public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) + throws Exception { + if (null != channelGroups) { + channelGroups.add(e.getChannel()); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) + throws Exception { + SnRpcRequest request = (SnRpcRequest) ctx.getAttachment(); + logger.warn("handle rpc request fail! request: <{}>", + new Object[] { request }, e.getCause()); + e.getChannel().close().awaitUninterruptibly(); + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + Object msg = e.getMessage(); + if (!(msg instanceof SnRpcRequest)) { + return; + } + SnRpcRequest request = (SnRpcRequest) msg; + ctx.setAttachment(request); + + SnRpcResponse response = new SnRpcResponse(request.getRequestID()); + try { + Object result = handle(request); + response.setResult(result); + } catch (Throwable t) { + logger.warn("handle rpc request fail! request: <{}>", + new Object[] { request }, t); + response.setException(t); + } + e.getChannel().write(response); + } + + private Object handle(SnRpcRequest request) throws Throwable { + if (SnRpcConfig.getInstance().getDevMod()) { + StatisticsService.reportBeforeInvoke(request); + } + String className = request.getClassName(); + String[] classNameSplits = className.split("\\."); + String serviceName = classNameSplits[classNameSplits.length - 1]; + RpcService rpcService = getServiceByName(serviceName); + if (null == rpcService) + throw new NullPointerException("server interface config is null"); + + Class clazz = rpcService.getRpcImplementor().getProcessorClass(); + Method method = ReflectionCache.getMethod(clazz.getName(), + request.getMethodName(), request.getParameterTypes()); + Object[] parameters = request.getParameters(); + // get handler + Object handler = handlersMap.get(request.getClassName()); + // invoke + Object result = method.invoke(handler, parameters); + return result; + } + +} diff --git a/src/main/java/org/stefan/snrpc/server/StatisticsService.java b/src/main/java/org/stefan/snrpc/server/StatisticsService.java new file mode 100644 index 0000000..9286b6a --- /dev/null +++ b/src/main/java/org/stefan/snrpc/server/StatisticsService.java @@ -0,0 +1,73 @@ +package org.stefan.snrpc.server; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.atomic.AtomicLong; + +import org.stefan.snrpc.log.Logger; +import org.stefan.snrpc.log.LoggerFactory; +import org.stefan.snrpc.serializer.SnRpcRequest; + +/** + * StatisticsService + * + * @author zhaoliangang 2014-11-13 + */ +public class StatisticsService { + + private static final Logger logger = LoggerFactory + .getLogger(StatisticsService.class); + + private static final AtomicLong requestTimes = new AtomicLong(); + private static final SimpleDateFormat df = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + + static final boolean reportBeforeInvoke(SnRpcRequest request) { + doReport(request); + return true; + } + + private static final void doReport(SnRpcRequest request) { + requestTimes.getAndIncrement(); + StringBuilder tip = new StringBuilder( + "\nsnRpc request report -------- ").append( + df.format(new Date())).append( + " ------------------------------\n"); + String className = request.getClassName(); + String methodName = request.getMethodName(); + String requestId = request.getRequestID(); + Object[] param = request.getParameters(); + tip.append("requestId : ").append(requestId); + tip.append("className : ").append(className); + tip.append("method : ").append(methodName); + tip.append("param[0] : ").append(param[0]).append("\n"); + tip.append("--------------------------------------------------------------------------------\n"); + System.out.print(tip.toString()); + } + + static final void reportPerformance() { + new Thread(new Runnable() { + public void run() { + final long begin = System.currentTimeMillis(); + while (true) { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + } + long pass = System.currentTimeMillis() - begin; + long totalMemory = Runtime.getRuntime().totalMemory(); + long freeMemory = Runtime.getRuntime().freeMemory(); + long usedMemory = totalMemory - freeMemory; + java.text.NumberFormat format = new java.text.DecimalFormat( + "###,###"); + String memoryInfo = format.format(usedMemory) + "/" + + format.format(totalMemory); + logger.warn("\r\nMemory:" + memoryInfo + ",Time:" + + df.format(new Date()) + ",Time passed:" + pass + + ",Total:" + requestTimes.get() + "(Average TPS:" + + (requestTimes.get() * 1000 / pass) + ")"); + } + } + }).start(); + } +} diff --git a/src/main/java/org/stefan/snrpc/util/BufferCache.java b/src/main/java/org/stefan/snrpc/util/BufferCache.java new file mode 100644 index 0000000..7db7c56 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/BufferCache.java @@ -0,0 +1,22 @@ +package org.stefan.snrpc.util; + +import com.dyuproject.protostuff.LinkedBuffer; + +/** + * BufferCache + * @author zhaoliangang 2014-11-13 + */ +public class BufferCache { + + private static ThreadLocal BUFFERS = new ThreadLocal() { + protected LinkedBuffer initialValue() { + return LinkedBuffer.allocate(4096); + }; + }; + + public static LinkedBuffer getBuffer() { + LinkedBuffer buffer = BUFFERS.get(); + buffer.clear(); + return buffer; + } +} diff --git a/src/main/java/org/stefan/snrpc/util/FileUtil.java b/src/main/java/org/stefan/snrpc/util/FileUtil.java new file mode 100644 index 0000000..dd63dae --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/FileUtil.java @@ -0,0 +1,12 @@ +package org.stefan.snrpc.util; + +import java.io.File; + +public class FileUtil { + + public static File getFile(String path) { + String applicationPath = FileUtil.class.getClassLoader() + .getResource("").getPath(); + return new File(applicationPath, path); + } +} diff --git a/src/main/java/org/stefan/snrpc/util/HandlerMapper.java b/src/main/java/org/stefan/snrpc/util/HandlerMapper.java new file mode 100644 index 0000000..1de028c --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/HandlerMapper.java @@ -0,0 +1,48 @@ +package org.stefan.snrpc.util; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author zhaoliangang 2014-11-14 + */ +public class HandlerMapper { + + public static Map getHandlerMap(Object... handlers) { + if (null == handlers || handlers.length == 0) { + throw new IllegalArgumentException("handlers not provided"); + } + Map handlerMap = new HashMap(); + for (Object handler : handlers) { + Class[] interfaces = handler.getClass().getInterfaces(); + for (Class iface : interfaces) { + String interfaceName = iface.getName(); + if (ignore(interfaceName)) { + continue; + } + if (null != handlerMap.put(interfaceName, handler)) { + throw new IllegalArgumentException( + "more than one handler for the interface [" + + interfaceName + "]"); + } + } + } + return handlerMap; + } + + private static boolean ignore(String interfaceName) { + if (interfaceName.startsWith("java.")) { + return true; + } + if (interfaceName.startsWith("javax.")) { + return true; + } + if (interfaceName.startsWith("sun.")) { + return true; + } + if (interfaceName.startsWith("com.sun.")) { + return true; + } + return false; + } +} diff --git a/src/main/java/org/stefan/snrpc/util/IOUtils.java b/src/main/java/org/stefan/snrpc/util/IOUtils.java new file mode 100644 index 0000000..1250e66 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/IOUtils.java @@ -0,0 +1,103 @@ +package org.stefan.snrpc.util; + +import java.io.Closeable; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +/** + * @author zhaoliangang 2014-11-13 + */ +public class IOUtils { + /** + * block until exactly length bytes read into + * bytes + * + * @param in + * @param bytes + * @param offset + * @param length + * @throws IOException + */ + public static void readFully(InputStream in, byte[] bytes, int offset, + int length) throws IOException { + if (length < 0) { + throw new IndexOutOfBoundsException(); + } + int n = 0; + while (n < length) { + int count = in.read(bytes, offset + n, length - n); + if (count < 0) { + throw new EOFException(); + } + n += count; + } + } + + /** + * write an integer to the output stream + * + * @param out + * @param value + * @throws IOException + */ + public static void writeInt(OutputStream out, int value) throws IOException { + out.write((value >>> 24) & 0xFF); + out.write((value >>> 16) & 0xFF); + out.write((value >>> 8) & 0xFF); + out.write((value >>> 0) & 0xFF); + } + + /** + * read an integer from the input stream + * + * @param in + * @return + * @throws IOException + */ + public static int readInt(InputStream in) throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + int ch3 = in.read(); + int ch4 = in.read(); + if ((ch1 | ch2 | ch3 | ch4) < 0) { + throw new EOFException(); + } + return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); + } + + public static void closeQuietly(Closeable closeable) { + if (null == closeable) { + return; + } + try { + closeable.close(); + } catch (Throwable t) { + } + } + + public static void closeQuietly(Socket socket) { + if (null == socket) { + return; + } + if (!socket.isInputShutdown()) { + try { + socket.shutdownInput(); + } catch (IOException e) { + } + } + if (!socket.isOutputShutdown()) { + try { + socket.shutdownOutput(); + } catch (IOException e) { + } + } + try { + socket.close(); + } catch (Throwable t) { + } + } + +} diff --git a/src/main/java/org/stefan/snrpc/util/LRUMap.java b/src/main/java/org/stefan/snrpc/util/LRUMap.java new file mode 100644 index 0000000..c5943c8 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/LRUMap.java @@ -0,0 +1,86 @@ +package org.stefan.snrpc.util; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +/** + * @author zhaoliangang 2014-11-13 + */ +public class LRUMap extends LinkedHashMap implements Map { + private static final long serialVersionUID = -188971896404993320L; + private int maxSize; + + public LRUMap(int maxSize) { + super((int) Math.ceil((1f * maxSize) / 0.75f) + 16, 0.75f, true); + this.maxSize = maxSize; + } + + @Override + protected synchronized boolean removeEldestEntry( + java.util.Map.Entry eldest) { + boolean delete = size() > maxSize; + return delete; + } + + @Override + public synchronized int size() { + return super.size(); + } + + @Override + public synchronized V get(Object key) { + return super.get(key); + } + + @Override + public synchronized V remove(Object key) { + return super.remove(key); + } + + @Override + public synchronized void clear() { + super.clear(); + } + + @Override + public synchronized boolean isEmpty() { + return super.isEmpty(); + } + + @Override + public synchronized boolean containsKey(Object key) { + return super.containsKey(key); + } + + @Override + public synchronized boolean containsValue(Object value) { + return super.containsValue(value); + } + + @Override + public synchronized V put(K key, V value) { + return super.put(key, value); + } + + @Override + public synchronized void putAll(Map m) { + super.putAll(m); + } + + @Override + public synchronized Set keySet() { + return super.keySet(); + } + + @Override + public synchronized Collection values() { + return super.values(); + } + + @Override + public synchronized Set> entrySet() { + return super.entrySet(); + } +} \ No newline at end of file diff --git a/src/main/java/org/stefan/snrpc/util/MessageFormatter.java b/src/main/java/org/stefan/snrpc/util/MessageFormatter.java new file mode 100644 index 0000000..1b59918 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/MessageFormatter.java @@ -0,0 +1,293 @@ +package org.stefan.snrpc.util; + +import java.util.HashMap; +import java.util.Map; + + +/** + * @author zhaoliangang + * 2014-11-20 + */ +public class MessageFormatter { + public static final String DEFAULT_PLACE_HOLDER = "{}"; + + public static final char DEFAULT_ESCAPE_CHAR = '\\'; + + /** + * equivalent to + * LogFormatter.format(msgPattern, "{}", '\\', args) + * + * @param msgPattern + * @param args + * @return + */ + public static String format(String msgPattern, Object[] args) { + return format(msgPattern, DEFAULT_PLACE_HOLDER, DEFAULT_ESCAPE_CHAR, + args); + } + + /** + * equivalent to + * LogFormatter.format(msgPattern, placeholder, '\\', args) + * + * @param msgPattern + * @param placeholder + * @param args + * @return + */ + public static String format(String msgPattern, String placeholder, + Object[] args) { + return format(msgPattern, placeholder, DEFAULT_ESCAPE_CHAR, args); + } + + /** + * @param msgPattern + * @param placeholder + * @param escapeChar + * @param args + * @return + */ + @SuppressWarnings("rawtypes") + public static String format(String msgPattern, String placeholder, + char escapeChar, Object[] args) { + if (null == msgPattern || msgPattern.length() == 0) { + return null; + } + if (null == args || args.length == 0) { + return msgPattern; + } + if (null == placeholder || "".equals(placeholder)) { + return msgPattern; + } + + int lastMatchedIndex = 0, currentMatchedIndex = 0; + StringBuilder strbuf = new StringBuilder(msgPattern.length() + 64); + + for (int argIndex = 0; argIndex < args.length; argIndex++) { + currentMatchedIndex = msgPattern.indexOf(placeholder, + lastMatchedIndex); + + if (-1 == currentMatchedIndex) { + // no more variables + if (0 == lastMatchedIndex) { + // this is a simple string + return msgPattern; + } else { + // add the tail string which contains no variables + strbuf.append(msgPattern.substring(lastMatchedIndex, + msgPattern.length())); + return strbuf.toString(); + } + } else { + // successive escape chars before the placeholder + int cnt = countSuccessiveEscapeChar(msgPattern, escapeChar, + currentMatchedIndex, lastMatchedIndex); + if (0 == cnt) { // all escaped itself + strbuf.append(msgPattern.substring(lastMatchedIndex, + currentMatchedIndex)); + deeplyAppendParameter(strbuf, args[argIndex], new HashMap()); + lastMatchedIndex = currentMatchedIndex + + placeholder.length(); + } else { + int escapeItselfCnt = cnt / 2; + strbuf.append(msgPattern.substring(lastMatchedIndex, + (currentMatchedIndex - cnt + escapeItselfCnt))); + if (cnt % 2 != 0) { + argIndex--;// placeholder was escaped, thus should not + // be incremented + strbuf.append(placeholder.charAt(0)); + lastMatchedIndex = currentMatchedIndex + 1; + } else { + deeplyAppendParameter(strbuf, args[argIndex], + new HashMap()); + lastMatchedIndex = currentMatchedIndex + + placeholder.length(); + } + } + } + } + // append the characters following the last {} pair. + strbuf.append(msgPattern.substring(lastMatchedIndex, + msgPattern.length())); + return strbuf.toString(); + } + + private static int countSuccessiveEscapeChar(String msgPattern, + char escapeChar, int delimeterStartIndex, int delimeterStopIndex) { + if (0 == delimeterStartIndex) { + return 0; + } + int cnt = 0; + for (int i = delimeterStartIndex - 1; i >= delimeterStopIndex; i--) { + if (msgPattern.charAt(i) == escapeChar) { + ++cnt; + } else { + break; + } + } + return cnt; + } + + @SuppressWarnings("rawtypes") + private static void deeplyAppendParameter(StringBuilder sbuf, Object o, + Map seenMap) { + if (o == null) { + sbuf.append("null"); + return; + } + if (!o.getClass().isArray()) { + safeObjectAppend(sbuf, o); + } else { + // check for primitive array types because they + // unfortunately cannot be cast to Object[] + if (o instanceof boolean[]) { + booleanArrayAppend(sbuf, (boolean[]) o); + } else if (o instanceof byte[]) { + byteArrayAppend(sbuf, (byte[]) o); + } else if (o instanceof char[]) { + charArrayAppend(sbuf, (char[]) o); + } else if (o instanceof short[]) { + shortArrayAppend(sbuf, (short[]) o); + } else if (o instanceof int[]) { + intArrayAppend(sbuf, (int[]) o); + } else if (o instanceof long[]) { + longArrayAppend(sbuf, (long[]) o); + } else if (o instanceof float[]) { + floatArrayAppend(sbuf, (float[]) o); + } else if (o instanceof double[]) { + doubleArrayAppend(sbuf, (double[]) o); + } else { + objectArrayAppend(sbuf, (Object[]) o, seenMap); + } + } + } + + private static void safeObjectAppend(StringBuilder sbuf, Object o) { + try { + String oAsString = o.toString(); + sbuf.append(oAsString); + } catch (Throwable t) { + System.err + .println("Failed toString() invocation on an object of type [" + + o.getClass().getName() + "]"); + t.printStackTrace(); + sbuf.append("[FAILED toString()]"); + } + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static void objectArrayAppend(StringBuilder sbuf, Object[] a, + Map seenMap) { + sbuf.append('['); + if (!seenMap.containsKey(a)) { + seenMap.put(a, null); + final int len = a.length; + for (int i = 0; i < len; i++) { + deeplyAppendParameter(sbuf, a[i], seenMap); + if (i != len - 1) { + sbuf.append(", "); + } + } + // allow repeats in siblings + seenMap.remove(a); + } else { + sbuf.append("..."); + } + sbuf.append(']'); + } + + private static void booleanArrayAppend(StringBuilder sbuf, boolean[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void byteArrayAppend(StringBuilder sbuf, byte[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) + sbuf.append(", "); + } + sbuf.append(']'); + } + + private static void charArrayAppend(StringBuilder sbuf, char[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) + sbuf.append(", "); + } + sbuf.append(']'); + } + + private static void shortArrayAppend(StringBuilder sbuf, short[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void intArrayAppend(StringBuilder sbuf, int[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void longArrayAppend(StringBuilder sbuf, long[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void floatArrayAppend(StringBuilder sbuf, float[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void doubleArrayAppend(StringBuilder sbuf, double[] a) { + sbuf.append('['); + final int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } +} diff --git a/src/main/java/org/stefan/snrpc/util/ReflectionCache.java b/src/main/java/org/stefan/snrpc/util/ReflectionCache.java new file mode 100644 index 0000000..b934638 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/ReflectionCache.java @@ -0,0 +1,89 @@ +package org.stefan.snrpc.util; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * @author zhaoliangang 2014-11-13 + */ +public class ReflectionCache { + private static final Map> PRIMITIVE_CLASS = new HashMap>(); + + private static final LRUMap> CLASS_CACHE = new LRUMap>( + 128); + + private static final LRUMap METHOD_CACHE = new LRUMap( + 1024); + static { + PRIMITIVE_CLASS.put("boolean", boolean.class); + PRIMITIVE_CLASS.put("byte", byte.class); + PRIMITIVE_CLASS.put("short", short.class); + PRIMITIVE_CLASS.put("int", int.class); + PRIMITIVE_CLASS.put("long", long.class); + PRIMITIVE_CLASS.put("long", long.class); + PRIMITIVE_CLASS.put("float", float.class); + PRIMITIVE_CLASS.put("double", double.class); + PRIMITIVE_CLASS.put("void", void.class); + + CLASS_CACHE.putAll(PRIMITIVE_CLASS); + } + + public static Class getClass(String className) + throws ClassNotFoundException { + Class clazz = CLASS_CACHE.get(className); + if (null != clazz) { + return clazz; + } + synchronized (CLASS_CACHE) { + if (null == CLASS_CACHE.get(className)) { + clazz = PRIMITIVE_CLASS.get(className); + if (null == clazz) { + clazz = Class.forName(className); + } + CLASS_CACHE.put(className, clazz); + return clazz; + } else { + return CLASS_CACHE.get(className); + } + } + } + + public static Method getMethod(String className, String methodName, + String[] parameterTypes) throws ClassNotFoundException, + SecurityException, NoSuchMethodException { + String key = className + "-" + methodName + "-" + + join(parameterTypes, ";"); + Method method = METHOD_CACHE.get(key); + if (null != method) { + return method; + } + synchronized (METHOD_CACHE) { + if (null == METHOD_CACHE.get(key)) { + Class clazz = getClass(className); + Class[] parameterClasses = new Class[parameterTypes.length]; + for (int i = 0; i < parameterClasses.length; i++) { + parameterClasses[i] = getClass(parameterTypes[i]); + } + + method = clazz.getMethod(methodName, parameterClasses); + METHOD_CACHE.put(key, method); + return method; + } else { + return METHOD_CACHE.get(key); + } + } + } + + private static String join(String[] strs, String seperator) { + if (null == strs || 0 == strs.length) { + return ""; + } + StringBuilder sb = new StringBuilder(1024); + sb.append(strs[0]); + for (int i = 1; i < strs.length; i++) { + sb.append(seperator).append(strs[i]); + } + return sb.toString(); + } +} diff --git a/src/main/java/org/stefan/snrpc/util/SchemaCache.java b/src/main/java/org/stefan/snrpc/util/SchemaCache.java new file mode 100644 index 0000000..a9c84cb --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/SchemaCache.java @@ -0,0 +1,60 @@ +package org.stefan.snrpc.util; + +import org.stefan.snrpc.serializer.SnRpcRequest; +import org.stefan.snrpc.serializer.SnRpcResponse; + +import com.dyuproject.protostuff.Schema; +import com.dyuproject.protostuff.runtime.RuntimeSchema; + +/** + * SchemaCache + * @author zhaoliangang + * 2014-11-20 + */ +public class SchemaCache { + + private static final LRUMap> SCHEMA_CACHE = new LRUMap>( + 4096); + + @SuppressWarnings("unchecked") + public static Schema getSchema(Class clazz) { + String className = clazz.getName(); + Schema schema = (Schema) SCHEMA_CACHE.get(className); + if (null != schema) { + return schema; + } + synchronized (SCHEMA_CACHE) { + if (null == SCHEMA_CACHE.get(className)) { + schema = RuntimeSchema.getSchema(clazz); + SCHEMA_CACHE.put(className, schema); + return schema; + } else { + return (Schema) SCHEMA_CACHE.get(className); + } + } + } + + public static Schema getSchema(SnRpcRequest request) { + Schema schema = getSchema(SnRpcRequest.class); + Object[] parameters = request.getParameters(); + if (null != parameters && parameters.length > 0) { + for (Object param : parameters) { + if (null != param) { + getSchema(param.getClass()); + } + } + } + return schema; + } + + public static Schema getSchema(SnRpcResponse response) { + Schema schema = getSchema(SnRpcResponse.class); + if (response.getException() != null) { + getSchema(response.getException().getClass()); + } + if (response.getResult() != null) { + getSchema(response.getResult().getClass()); + } + return schema; + } +} diff --git a/src/main/java/org/stefan/snrpc/util/Sequence.java b/src/main/java/org/stefan/snrpc/util/Sequence.java new file mode 100644 index 0000000..cf3c277 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/Sequence.java @@ -0,0 +1,21 @@ +package org.stefan.snrpc.util; + +/** + * @author zhaoliangang + * 2014-11-14 + */ +public class Sequence{ + private static final Object locker = new Object(); + private static int sequence = 1000; + + public static int next() + { + synchronized (locker) + { + sequence++; + if (sequence < 0) + sequence = 1; + return sequence; + } + } +} diff --git a/src/main/java/org/stefan/snrpc/util/StringUtil.java b/src/main/java/org/stefan/snrpc/util/StringUtil.java new file mode 100644 index 0000000..0165559 --- /dev/null +++ b/src/main/java/org/stefan/snrpc/util/StringUtil.java @@ -0,0 +1,16 @@ +package org.stefan.snrpc.util; + +/** + * @author zhaoliangang 2014-11-12 + */ +public class StringUtil { + + public static boolean isEmpty(String str) { + return str == null || "".equals(str.trim()) ? true : false; + } + + public static boolean isNotEmpty(String str) { + return str == null || "".equals(str.trim()) ? false : true; + } + +} diff --git a/src/test/java/org/stefan/snrpc/Client.java b/src/test/java/org/stefan/snrpc/Client.java new file mode 100644 index 0000000..1540671 --- /dev/null +++ b/src/test/java/org/stefan/snrpc/Client.java @@ -0,0 +1,28 @@ +package org.stefan.snrpc; + +import org.stefan.snrpc.client.CommonSnRpcClient; +import org.stefan.snrpc.client.PoolableRpcConnectionFactory; +import org.stefan.snrpc.client.SnNettyRpcConnectionFactory; +import org.stefan.snrpc.server.SnRpcInterface; + +/** + * @author zhaoliangang 2014-11-14 + */ +public class Client { + + public static void main(String[] args) { + SnRpcConnectionFactory factory = new SnNettyRpcConnectionFactory( + "localhost", 8080); + factory = new PoolableRpcConnectionFactory(factory); + SnRpcClient client = new CommonSnRpcClient(factory); + try { + SnRpcInterface clazz = client.proxy(SnRpcInterface.class); + String message = clazz.getMessage("come on"); + System.out.println("client receive message .... : " + message); + } catch (Throwable e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/src/test/java/org/stefan/snrpc/Server.java b/src/test/java/org/stefan/snrpc/Server.java new file mode 100644 index 0000000..7b07468 --- /dev/null +++ b/src/test/java/org/stefan/snrpc/Server.java @@ -0,0 +1,22 @@ +package org.stefan.snrpc; + +import org.stefan.snrpc.server.SnNettyRpcServer; +import org.stefan.snrpc.server.SnRpcImpl; +import org.stefan.snrpc.server.SnRpcInterface; + +/** + * @author zhaoliangang 2014-11-14 + */ +public class Server { + + public static void main(String[] args) { + + SnRpcInterface inter = new SnRpcImpl(); + SnRpcServer server = new SnNettyRpcServer(new Object[] { inter }); + try { + server.start(); + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/java/org/stefan/snrpc/server/SnRpcImpl.java b/src/test/java/org/stefan/snrpc/server/SnRpcImpl.java new file mode 100644 index 0000000..df54e81 --- /dev/null +++ b/src/test/java/org/stefan/snrpc/server/SnRpcImpl.java @@ -0,0 +1,12 @@ +package org.stefan.snrpc.server; + +/** + * @author zhaoliangang 2014-11-14 + */ +public class SnRpcImpl implements SnRpcInterface { + + public String getMessage(String param) { + return "hi,it is message from server...param+" + param; + } + +} diff --git a/src/test/java/org/stefan/snrpc/server/SnRpcInterface.java b/src/test/java/org/stefan/snrpc/server/SnRpcInterface.java new file mode 100644 index 0000000..74bd36e --- /dev/null +++ b/src/test/java/org/stefan/snrpc/server/SnRpcInterface.java @@ -0,0 +1,9 @@ +package org.stefan.snrpc.server; + +/** + * @author zhaoliangang 2014-11-14 + */ +public interface SnRpcInterface { + + public String getMessage(String param); +} diff --git a/src/test/resources/config.xml b/src/test/resources/config.xml new file mode 100644 index 0000000..a4f9341 --- /dev/null +++ b/src/test/resources/config.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/snrpcserver.properties b/src/test/resources/snrpcserver.properties new file mode 100644 index 0000000..e154b8f --- /dev/null +++ b/src/test/resources/snrpcserver.properties @@ -0,0 +1,10 @@ +#tcpNoDelay +snrpc.tcp.nodelay=true +#call the bind method as many times as you want +snrpc.tcp.reuseAddress=true +#ISDEBUG +snrpc.dev=true +#TCP timeout +snrpc.read.timeout=25000 +#server port +snrpc.http.port=8080 diff --git a/target/classes/config.xml b/target/classes/config.xml new file mode 100644 index 0000000..a4f9341 --- /dev/null +++ b/target/classes/config.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/target/classes/org/stefan/snrpc/SnRpcClient.class b/target/classes/org/stefan/snrpc/SnRpcClient.class new file mode 100644 index 0000000000000000000000000000000000000000..ac9b009c81000aec569f219049400f933141b02d GIT binary patch literal 296 zcmZXP$!Y>Y6h-fAhjvO3vdvb|jfJ?g#f`*OAdv1KD2uXfX{ws4a{9F_@&Wm%kf&KF zxOtp6-OK&?{rUzl#dC~^@M>Kye9#+dgg35IA~m0tT9$=2Ax53h-^qg%r8K$tSnsq7 zghu7;=}Z_5-*3xhDZNidca#6~gwT0ADP4ua8Xu!gc)5LLTW61QU1~x*Epj8n-Z4++ z+3Zni@!&VlvSg8rxUx%X_fF|maS`j^#TZ}gngl|PlLN%58fYRy%w3)5Ep(V7beVfs Gdin$SLQW(A literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/SnRpcConnection.class b/target/classes/org/stefan/snrpc/SnRpcConnection.class new file mode 100644 index 0000000000000000000000000000000000000000..819c3f477f985b35011c935f6dd42f458ce33817 GIT binary patch literal 398 zcma)2%T5A85UfF##a$ox_yCV^aSk3i8a~CO&oo;WUkl8A*P^IJbHZ=R@?iAXBC02l96jssFwM#aq8_S=k&sqvH nCpQB!xkZMS^tp6Rsck_DlpDz27P5~68BjP(Rn#4M8#wv`I5cE4 literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/SnRpcConnectionFactory.class b/target/classes/org/stefan/snrpc/SnRpcConnectionFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..02d846f059c2bcc89ec7e3940d374c68747cbdf0 GIT binary patch literal 321 zcmaiwyADA?5QhJ8TlYwmT7t$FN~KUqB#3@()Ckf>(2#td}D|u8llJm`h z`-EC#(vO+Y?)7K?kRw8Qa@8gd{6wHcXnx46op%?tIU0iSM&ESEI=%nY{+hW|LyL7$}&-ndqY+#Fh!Yu9PV5i`tc*-6nzQ;L02YZVw0AEYB4ELSIn zY%F4`{ea_jJ@7sHy^W>kO9|2g0 zI|>21z~|@C8=!;D=fMC)mnM7}g;U2XHlLviM#l>xv zA^~;FskD)oU^@z80&`0?_8zsZlQI?+i}137mjo7+X3Onqcm<0E=41@F$4KW0f|=>g z=?-I`+v+#$36m<8V3~rY#IdB&o6^vNR|OO*+NqBa)_G;yQ?AsURPY*Syse{dHWw!u z$Bew|*=ja67^JD_4cIu*Pw(DvN{=_0!bc>W_UgH>$`KyhHZ<6Gik@Y(S5! zhAjez{dg4TeR(#cq>5U`a^VGb5K5ZGVEpBV^CwpF@Qxzx$CA`KSGdhF5Ak5nmq z=Hg-&MTMU^D--XtG8w~8M)1Bsi}bLWO}g1Gq*n8gp3NM3t>YK~}o&>wAAU@M!l&l168mXS0AskhZsaC@?@uMM&VF8WZYAPs!`DHDu6pM-> z_>2I)PiVGF4)q zvPSK+u{A4iIZYKey$)I5tbtxOQ`>V>9h_*UCj`~MhINVX18f+Gg<~OZPsD1150RX}TLJuv&8x=Iolry~A`(%#{64lOBC$wJ znZSDiB%*iGl~C_vcf;PAhX@V?L*6r{q*4Q+n3|fvz91gp&_GNb$48G7wNghcavyrE z_Hk((9fR>3qA~e?ET6}|XVezHz-7j4;U0ey0g2Wy7V>$D7@Q_zXV8YT=;V77K1DA+ z!ybIjW_lij9A|L>Icl+Ri90THbOl%W`v%wW9p86xotkgp2i(LjxP`}j|Bl=E17G1U z-0>JWQ^2~&2vMiDyvNd09Ea_(`VpG1-w3XKu~gxyPu)2+Pt@FgM#e}n>Lp&80NpOsUEa{gVD*HT~5nEzQgS+#&NTH XzRH{q;7jj$o2W6vxmz&bzeeC+31GTg literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/client/CommonSnRpcClient.class b/target/classes/org/stefan/snrpc/client/CommonSnRpcClient.class new file mode 100644 index 0000000000000000000000000000000000000000..c0a255a0fd4fa59fcd724ace384382aa81528b93 GIT binary patch literal 3901 zcmb7H`FGS*6#m|{G-Vp-qST@V2JJxGfexrBWoi`)=xAw?)=B}FG);$;G#N7)3hv^D z`@Z4EZ~lrKEppV~@Erdr^?OO$q@AhaoHLW;y?5{Z?svD$pMU-G8-P1-Q9(kW%W(_Y zl4ne5cD7`@MLnxqreS;80cU2$u}AD9MSZ|uQBW(;G_9T1vX*8SvcnV8hVCh-6KJnc z5|b0Cvz$V~a0NCDRvhG3cF^C>2{h}DZBwb~*atP;bKJ88SSb@IUw)MG$w*${*8dcw zgksvKol_Fq?#kmUG11`z$On>CQs2juw(0c?)O2=@3DgcalSUFZV4Z>+iR53r4*gWo zikk#h7Yr|8LtsbeU_|zSrIkv#DqO_)TMdErDiqWUG!B}!F;t$JFx*jX!ZHL}1|40q z#x&QI&*5TSUx<5KXQlfq(A+haL=85nXh)NR%>s8-xOZK|C6U5yQcH)xR2B0pDalnL zUFqo3Ky{5thPJ3!gS84e1vWS?Rd7(?rbuhB zysvCplZKnb19(tDo>8sD%6V|YTr;{vx-I1@Dh6;DE=C$pMs3v|cxG3eE~7>A1?U;+pTy1uUJE;Eol zX<)J03Un|Q6)2Wxl?-e_#Yva~4Q45nHzs|CkICIrGOd~<3o|Mv!N9L7y3QFU4zo52 z>O$j-RzhFcEJw_Ot$AgavOD`m_r#>aGyN5s`bI}{{kbmwCQ(9J0Ud9QboX6$BWE)zYZNQrP(RJF-agYsm`f*8Lx1xYQ>^qlhW;RtzmIgY7Gm6j?c>EEa7z( z=kbQXS{YzDUj`kGmBS&jq}pOzlzj{DD0q8G-MPk;#i5-&EW@YbUA)K2v5i^(Id7Ld zjb$b<5l0zUdOQ|5e?6Y33(DoR)iv3cAJFVc%Wydiqj)Ul#M(usd`;{ou~UI^f!3v? z@N98m9JVe$9Ha~DSJQQ)RO;9vaJWiOU1|PQ8CA;*MNU(J@yNtZf#LsS;yQ{^T9}C} z+%B-GS`9~?gsna~;*?$8IB3duht`Uh!5+!IfSTv~n(OmwaI~qucj1c>Hq&ekzpGG- zo8@Z>Upo_W6#7@r6#vR$%xeR88_~qm&3xL)tNg5P5%XyI5pCb|AwebJ;Try~r_wfx ztj8_>4k*x$4Wals?k2dN?w-TO?yE?RcZ)gP`ZLm*Kd|O1wvM-S%^~x9cjjmGNYypI z>YGu=`wpVrL=C#i1k{t3IUL6w&) zxKAKL5fHwc@$036oNrlLp-{+#^q+BVqTT`Q=T zR2%&Zg4)Vl07rZS4sm^m88b`*kN8GYf#O&|0|M9c^aOOml&})uck0M#5z674~dA}IuesAV7+zZ%z6|>_q1bjR@k7pT!mKQGLB?e*+ul~-}*J^)7 zX}l&gLU`$UyeYxSdIdHT7GUysnzWrFuxaM}47vzl7q7DPf|}@Eq_7w7;{!tckb6Ov z$d!+{5@t!dsU9EW6E4Us*+Sg1QtP@ibNEyyT|6}&^i6P|GN0jd?nORJ=`^)S>Q}MO rzgV7E<1yh2_%bxu;S111Ce3n*wgm|q`pSp$HNN3hw$Bv5-y-o3(C)t# literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/client/PoolableRpcConnectionFactory.class b/target/classes/org/stefan/snrpc/client/PoolableRpcConnectionFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..b2629564387524b32ce4ddafc1351f5a8f4785b8 GIT binary patch literal 4803 zcmbW4`*#%O8OOhG60*r=mRpvHAa~G^0Bb>_5{e}VG?+k0QjoM&C$p1eV0UKSnS`X( zw%TgNR@!>))z-^7{ly>joEnbhoZ6r4IsK#BexG?Kv%8ZFNj;tuXW#dEKhO8Mychoc zpTGYDz%hKBL6gEGUUj`k>aQLSO694$3QLv5&}9SYkGbil}9hr-TUdt96?l}0?r4eaXKdCRUyC$(Xh zLS{<$Qx*?kk9gjzu%&ybwsI_}I_`7?-*2EDS%nQlj%#0>El=9jap_Qn%|o7Lmadpp zM}9|xEy0ZAEA%Z-<{CPj^~j9{rgdZ3tVF!rv>nuTg2Mjp)mx94Y#g$m!4ZYdT6E(x zRqv)KmdrnF;2SuqU`%>d4(seH%{J7LNZ0$531gRID5jtx1?p)StZY>%=PRC zXU+_4?ID9R4GD`=*}?Pctbu;yvlzg6X`OE?Y^`sdIJw~_QG{=)OJr@9g^mPipMrjZ zah1&*k%|ti!zBYf=w+hUtx1n5+)qC|1IF1){s_+%@yBCjbk-Fg zKQJ&a_Fe9ZCJKAFe9W6#Me2_XydY9{`u8+tTM#EwF1Z8Y?iCF$8~BM-#t7;r>P<(( z4JM|q8u(eAsh;2s8&R*$I69GH`?`VG#5O0`c!tM;7&FlWc5u_Sbpdoj{95jB8~CLJ zv?I8eCG$qu)frOeXUti?4vNxDo-5TK(A9s-z_0Ne?#`PlnW=#+Z-e&?oJOB~{m#I! zY@ZcRkqNQ*qk+p9m9O^=Jf&Ct#lQ&q*bHOdY}K;QF$=8R(*3j2tKx_pl?u1(c6xMH zt$H#oU8$krn(w_e-R;=Ju$s}tbA)d${>N*KPp~GrD>;)3zt>|szc*kb|8C;QEws=A z*xz#pn|tnJ%Qb%7_c^xp{tLOgc;MRRop-SN%bwoPvF|h5HRAyP?nN8_c5!Vdy>-%4 zp2Yk3cPn;c8}`x5gP}#p#zW}lFM7c)YT|2(-y5L*OXH>tRE7|6m}eiw9O8Eie;p15 z9_N?hNJr1#ux$~Af8yAu{Mi)hXbq?KguWz3nnk`8j-ziGY?LFSDA)Uy2KFxE(OOvR z86GILg#ry~sfCb>L&)(uI7wF$LNk1aoJlJmj zoPNc(sufl@<3t^p|4xY-Uqz`_a{LgviA%@$e?fGysAD|5u$~`R6@HI(EuS=h!Wmso z&3&$p+ZA)W8oM!1B=70S!D-^fLA&(e_CEly+YipDY&0TeaDwd3htF8?iO*cr{I1b;rN(I!QD#Y-XQLF z3hoyXj?bGI*O#}4WB_hDk$gp0KStR@9b_{q?CfmNoMBG+&ka>?vMHFpFjQta0#0RdKkw1pk;?j zG`X}x8FU=m@mwL5U6sp1sfTMFr{qg19Oe3QWWqq2p>LCa#chwvmc3Hnq%8v{5=)zP zKMZZDHEpNONzt=Q@wn=Cgy%{z&mH9l4;fCVwi}L&lV;^OAc~}U&6TeDkYOTsJk@-S zAzkttA`6BWEf~m{NTJt47JUqS~X zwuK=KlNs(fB8;L{Juc@55ai1yC0LwWO}9mUy@j_8j4%v84Q}6I3-90p!zm(hP4LFL zyCwXtih@_pAkSc^SY%+7VRAoDl#C5e1a@-B-eY4S-qK9HYheub6Tc@ID*wyxy&>u< z*RwU=pqRx3E*Y3)7>tT3+H!p9bb~-wpFVY)a@@juxXfTJl`EBUb*{9sJX>WrUpZ8X z=q%uUozqhc*JIevz_IuoOZnPKT*Wm5l(rZ4Q~8Vnw=fN=O@lWY6&_M#rgQNvQOBsN zz?H4y^HM&EMKNE?;076M2#3lxFmRK>ekw;oL8a-rUsGJ8v|1Anx*}9_GEy=zi+KZc z2X(tWnyZ1Y{Cc-peQeCaM_7pKwJbx$r9;hNGO5@9G|fZJP&{U^sN?bR!7Xc#b}8z< zPas4DEHRk8)e1z5Q|mOa!f<7OFdpT#_Smu8N_Ff7`YW}&^8U2MwhVkiUF`@IhaF#rVm1zpi5eC&_>@YfA(|dnI#!=COdS=cFBK(z$=~V( z)M)&`#9j1e@C5-&Tw^$Tqokk(dz%9*Q@^h&?%ZGEouq-ARlgfJV&2s){_H{T-Iy*j zdJrg&JU^tgT@tG8H!QUEYhhBoCJ!T3Xqo0g$>U)tLh6~+kLdRTSYMxhW$4B2pDs87rcN+4kwy!>#M5cG7{(^@G>*Z; zWo)5H;|)mMf{#1s;2w<*9w4Caw+JJjhho1HpVRn;p0h8>>s~s?Q748Rx`&?ezcFUu Zs;0X^f*uIE9CZC40dQ%i3D@+|=U+Wol#BoX literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/client/SnNettyRpcConnection.class b/target/classes/org/stefan/snrpc/client/SnNettyRpcConnection.class new file mode 100644 index 0000000000000000000000000000000000000000..3bf6a8d62e274d6f17e471c7384c008f49b65c6f GIT binary patch literal 5754 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 BBToPT literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/client/SnNettyRpcConnectionFactory.class b/target/classes/org/stefan/snrpc/client/SnNettyRpcConnectionFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..9120307a56b0736a981697850d80020d5c2823f0 GIT binary patch literal 1203 zcmb7DZBG+H5PqgDoLmnIrBuPH1ws0PoQn7ojENx-np7l~H1hFS)^bqpn!5$%UumKe zCGn#l{87f)YeNZDiMibF&Cbj-^E^BE^VhfU02c7nK#Z{92Ms$^@~z|9p%=7-Et; zn_eznr#t)_6^_ z^@e?M-qWQMSfx{>w#vB^jC{uEM?Q^VjMt$kB83EoF~U!l&+_doT*WoEI3MGfU`+jW z9XZY<+`vuVZ}C}zt$b8(E&2wsrOTPvV@4bR literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/conf/RpcImplementor.class b/target/classes/org/stefan/snrpc/conf/RpcImplementor.class new file mode 100644 index 0000000000000000000000000000000000000000..6f35047e0cee0a5007ffc043e85a26027a341900 GIT binary patch literal 1451 zcmb7DT~E_c7=F$+HdzK^1Hn&}PrHE>G%GoICdX~1+=%s(gTTLVy zFZ==i854hi@j2~;v0~yb+MV<6eV?z>^W*oo?*P{EAcvH|yz-l75Xy$-nStlGZPQj> z!+g=UcUx^&wxky-KZlIK*opPpGF{7Sn$HhUq#fpv6_|*sjxrCV?^v$$&N_4@n}cXu zmwwcMR)3d^kPlAd5|2L~!Y$>#4c&v`LZ4D-{QnOXdlz|E<#|~5@d}I02^ku`P0V`;k zdp-S}&u%)N6K)BljY?f0v!jk=9%)P#P{z1GvF3R4S*LX<{g<)Ra!uKmTes+*&b!4- zc8;eKBN<3^?5BReOPRqcEj0(S~1V1&^ai8<|MDpA&hm3kg?Sjb^s zV0n0+k-lyJjkOdcV=7WW?;#4TGNM78Fx4V~ zFM_NYgJI}|^9QQq+wzH{Z@~D)E3~3NXUx!Ln$Hm5H;}^>u7`OWQ^@n->2W_A?Tg$q z46d`R@!R8jBD%M{N&FqEe!z9VJ0zIUUXscIR6hs_tENz3*Hvb__AGki1RidP@_6MzpHTVDk literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/conf/RpcService.class b/target/classes/org/stefan/snrpc/conf/RpcService.class new file mode 100644 index 0000000000000000000000000000000000000000..fb899237974155bef5097ab9a3d5e05711b11942 GIT binary patch literal 1783 zcma)*+fEZv6o&uZ1BEimsT2fM1cbI6Mnyb9xRAsIZ9pv{kt?TVC_~zrW;&4gPF`pt zG4a9&@S%+Vni=WPL&D9>-s|wMZ?CoYpTEC;16apq3NeLQ$F1s3&pa_~y=l9Rie7Q- z6a8bOQZn5Ot74{*P#8WlE)2b9*j0VMd}dZWg#qtN!`!JE&8EUgvE}zooAj5gs%?1Z zuBnh|_iq)p84|OO6-FbzlIL1>m7auc)S1`sT$panF&L(f6mAo5x8A6kb<_47S7EW( zlRgqhy}m8Ww!CeHrCevZPD}of2s_TPnMNEL4Z|2$i0AT$15lXIpy8IR?r0c5T2|8< z29Z`6Dq6O=cU~`>?txLR@d%?ur()C&4cC%=XiRvg7TY%08$WD5(Y31S9kg0Kmdi(Y z|2I3^X_XcW+Jc58`l!>qrjv;_B9M_&Pjr|?M?Bf<2O&{-m?QyrIibuohO1E~Sy$ZS zQRUDpx+$jb`O{7@GFYXp=Kj^>*>}!G|ul$t|#8_#Tys?mQ&abP}Dly5z56pk#B1T#G2LTp*VJ!#}6yTOFC^Eo<+{CxRUH0FnDEAnSPA1!SYWBcHp1JjaU;5Z;=N Uc92toSUo`G0SU-U|LCv&0rF2T*#H0l literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/conf/SnRpcConfig.class b/target/classes/org/stefan/snrpc/conf/SnRpcConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..a5c1e554e17df0b12e4484bef53050a5a1c07ecc GIT binary patch literal 3533 zcmaJ@`*Raj7(KUb*pMt((o!ghMiFcZB*lVY3n*ZbLRxAIRZ4wq(@og2-3^-!g7|*F z-!Bw=E9&@z!c2=YBfrUvGyY5Bxw}iUZCWNX+1+oyd+xdCd+k5}{rMMwPW+;vPT)4% zDP&5np4Y5Q$#ROhOwP9QnIUVinA^=eqoANcpm9Pwp=C_XDr63fP3SpSV1a2D3c4e( zDqDlWSDCE$x?3P#s)7luuJxY1BiF==j$PCp*U(D>Em?2(vTK-`fr_18(QP@?unc#H zKz&=|RIM=KBM9yO>+oRoX5lB-!cy02-QgJX@ba?3kZD2T>*N32Cdu9iF2 zrxk-;7n`;=Ue%cA3X3u1I)+u~P7TMy6&+<$SE7&Kntjfj@*{-r-@+?tg*&C8!f%Ar`CnaVwukm)A zA}3?$#U}Z8K*azaWNK^0qHb~94fAvM>T1SrPk+AE5N)D-bOzsz>=6!mpq!siyG~^VFF|}$kv0Cpc z#=(k<=#FDE=X8PDq$P#ARC@2W5s7gLqwp?RUuP}R0R z`sAcZY4iSExnDogXR{4i$-tIrpNUYQM|)M%4?>~)%Wm$g7>*$HJH0>+tf8n z#fP$oszuEy>4A-S1Q1wEdV}m`2boBAnZe;Uy-|F|tnjyyjV>+IjBlg(oQidJbacdU z7GEkjH)FeAwlt1(6<^_NCYZM!ZOo84bWQd0yb||-*M9tgwAXcu1GdABzNbV!fuppg zi=OdEfw~PFNkKkx`H zi}cws@{3scJI!@i#s8S+l;FY^+~Qf~8_wkbq?1=cd!&6D zx6WR+91UpomPvOyA?fj1NUpaB06hVV<_lPT6^kxIki(jbSk33(xTfBtvDiD=%{!;9j z9^3n+$7S>$PVApXA7A!QVNm*aHLU;J^BO*n=B~&EG`B{kaHKWz2Oj6gMZ=XFy(a!u zth|i84}CNYJ#poCYSV-@Bt6ROPX555wjcd`9>WACdG*geLAgP_6s*P)+(GZPRP|0O zv6ect5hKN4I|uGM&f9h(ttV2NV=Y6x4o;elY~7tiO|undh}{93wr8*jFJUv@=gQA` zJg#Xv?WK8xUzT_HHre1+i za9rUK;&t?41*L2Jgo{+ov_Q`K(Z*{;4*5gztgE}r{{?IBrMJxZIM*`9r>1avHpC7OqQ!Ts2oR@KQUD3|Yyh^8hnK~sN-(C; z=_x!n8*P_|mh}B9Xlj7QwRnNJbwqp-hXUNa^p+$WiJN#S@d{zHBpYJtSLA*cayG=a zF~E;A6t4wrUuVGlQlEkPX5wuR^%CCwl{ZTt7{m2~fYN yq9&N+;3q~sjQCM|fBqk`Eh_^6 literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/conf/XmlConfigureParse.class b/target/classes/org/stefan/snrpc/conf/XmlConfigureParse.class new file mode 100644 index 0000000000000000000000000000000000000000..36446edf5007c31a72c4920ec14ea5a9fbd90ff3 GIT binary patch literal 6092 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 literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/exception/SnRpcException.class b/target/classes/org/stefan/snrpc/exception/SnRpcException.class new file mode 100644 index 0000000000000000000000000000000000000000..93fe189ea7987974fe268ce889610e0998eaf16f GIT binary patch literal 819 zcma)(%}yIJ6ot>t-=Gi(BoIP?7Fgv6F$*L%AU4oSsiH0jjnt)?y1^*%L^BTXBs>EW zD^`(M@Bq97Z-Tf^rjQ0Ibz}R^oco<~?Z@Z)2LL9JboBFutefd*5NDxZr;zGC`q1*0pUmMkxum1^ip$wGhv}6!+`;Yn&fxZ!D4t*UO zp-oG4`ZD?R{N`!*`nFC;?JKR!0U=(lvjKF-#%BXTDWlGsEZSfV?NG1I*kFC0Sn6ECps+oW&fUG9wY@k>kn&@)6*G zl~$Xo)&^LZB;?pUKO_`Js))dP6tKh$%PM}vTApMTn6>l|)(Tc5)>_1>^Z51xoN8@r gfKQXK5(iir!q!K!*I-T*j9Xc;%CQOS42ogn1zjqeXaE2J literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/log/AbstractLogger.class b/target/classes/org/stefan/snrpc/log/AbstractLogger.class new file mode 100644 index 0000000000000000000000000000000000000000..deab049fb3bd0cab97b15c54d58ad9dd60c9086d GIT binary patch literal 3130 zcmb7{T~HfU6vzKJBrL>*P$*bhTS93yBuH$l)k;u8|p){yLZp|pL2fa+#C4mpWE92 zPC-`?66iCnLb`10E1Hom8`gS0T`~*l;au6aw7i`$3kBU$5Ef{=u5D`Rl4carGr8+} z-d4~ka468-brT31+L|uVp4su8x2>X47!qhaTQrLHIf2eZ?d$$5okz@NJ&FdjsAxv3 zKtrNGtDsHb$d26fMyWJw77bgs#$L_q>vqvJn$RxrfSW^HW)NS~UW*&19na};gARjH z#IRqgMw=nfr9wfIKrB-<^y!VYoNg^>xssE(nb%5L%__=gZ!v7I7Rv(1Gl8Y=CdWEM z#+pFOyshP5p3>GG4FyMb@pPF8CXxODdM6&58fnIeC~wN^)WZqVwj4mDk6M za(j2|-mHUidxU!#sezveKkf2h;9=Q?uskfdavz^w;rkG;2a>m-rhY`r*N9zd-**cg z-y~CCpz~9{Yry@EUxeSS^o~)dje6}|@4x})ouh$n9OM(#aELY>W8TLg{-tS1fl%0g zaJdI@FMOI;!L>;8b98>fn~)Q$(OK+vv{l!@(-yMbT#>oI&deHk?GaO{?f220N^OUi zPkx8Kn`m+GzeV5FfRy!@(90l438Rn6A7e%jIbq_iRHcL-9LIwU6ml#Qyvkx&)ZaKv zU;c=2pdo)uI6HhJDSpC7BXl41Xm{Xv8%~zsohN=qp|&LhdO~%unW-Kr#iA zS@q>xpUgxcnP;oXOjVO9lZ;I=o4!c*NM_=AnWN!|GVSayyDctCKh~q`D^zi^db{sinvKhgdfq@6_cx zR?I6w=vi@zVRGB?o%lY()!e|*wR~GQD<~k3^Pu&@1F$! zS&4RrN^X2WgFoeNX^5^``w8#F!HpeI#V?sfPP_K>9n8N~Go{`n$MQS{q_G5u{3Wl{H+$=L}bJV;vZFH0%lo z#pZF9q@dyp>?_z~$jZD%Yt!&0zM?!%MY%LD+hgY7+o4R7UMI0fu}UfqP*YI-HCY%IfzC+01M4&y8PyDW zVTV^7IaDJfvLRT&GL2!H{(5NS#4OS-LwlNVdQQ`+M&}f**?i#~YW@YZ*23&LF8_-8 zpUIp;mY%Z`Vx9mN=$pkAvb{05hO4v_pDeZOI)O60i5m&{x;zs~`X}-jU`>(@bvn|)M{i+@5X_F)K0(vp%D3IpUR z^#TQ7$2}CWN2@^tcnBR0+>wdq2gzK})WjpK%CeiN!;~a8$-7CoM}$b-Slp!d$Fxu3 G>wf?q25Wu* literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/log/Level.class b/target/classes/org/stefan/snrpc/log/Level.class new file mode 100644 index 0000000000000000000000000000000000000000..ae97459c7b104d6489f3ae39604eeaed67cf25d2 GIT binary patch literal 1430 zcmaJ=ZBNrs7(JK0v?~>G^8PA!FT0jgNGwOQA==xjB7mR_iGvOm5(hE|-6~`bLLBs|2yvir@I-}zAb%TFQ4f`& zQL`K~Q`y@x-3?>QHpzol%o}#ra4n9-M+H8F$!YnsRbr6K#S144&5`I$e-efn+OFH4 zt6287>B<;oP`+rzf*8xRf+39YuE!Z#ZfQ1}<>xY?;w56_z%lkrPMK2i3a{y)jQxGn z*=88IjeEnJXCfhEnt^@gN=X$_E*(5D?21Y4^+lrhj!?lY<|L#TnreDHq}c7Ln8yM` z$Z%cbFkjq1WQf)JTHD$+^X0^Hjj#WoXs8U5@UXVSFjhnxumDxcs;CrGQ7NIKQaFL8P99BS1SrN2&_Mh~Lf_!0Cr~&8%Y~bKCwO>- z76ID)0<;Uz84#dLfS#ZLy#hRz1n8H4k%F&^7Cq;$qFv7gs_4>l!76(7oK!`>euRM^ z^s72NrKds_WGO`#>6!S-SLmL4#>S~V-k=m4>OR5qD`Jo~z$2;RT|$I+Nbi(6k3LUi zzOUm9L%HzC3F5J1yg0^W_zgXdk@!xF7fvn&8-D=xN00kKB|JX0cN&{RX?6SBDS6;R-ZSSN{RY&@21^ literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/log/Log4JLogger.class b/target/classes/org/stefan/snrpc/log/Log4JLogger.class new file mode 100644 index 0000000000000000000000000000000000000000..2605f02a005e05a399d157226c7dca192331dba0 GIT binary patch literal 2430 zcmaJ@-%}G;6#i}qY>11dfWNgyi8cwER7k6UzXBu@jX(j7Xsa$^NfyIyy4hgcm(JLk zKJ=vz<$qwN(+8Wj=(HUl+nLVvU#k7?ZV==bGxy#-_n!0JbG~!V4gdW2`)dIG_(FkC zAZ*#CWX;hRG&5N zt*RBvx`a$EN>Jhr2}C2)h1|@@*yEY>a6S{EV#MlFdt!<<0d6~i=~ zYXS$O`9*D6OI9?ql$>^K!z>NO?g{uuta&|%7Idg+M=*#3cuzq{;P5U^sOUr&9WLo_ zoxiXX_O3y+gWjlUMVr8ZykY9&^`$x8p3&wix8hao^KBeLWP6~7wwVb(NHP7YA85Lo9(n4kh zve8{!kdzN?Vt8V1Q7<~1cV^1A^-Nw%+S_psQ3W3e9NNyZgi;YhT%dI{Gko`^z>yuu zbZ-oj%kwG}TwvhQ*uz{qlDMegLxE!wc{^7gdLR0Uo=wlB^8zRKiYZ9Ik5qh&O9F~z z&l{%3+9Gef>Kq1C3`$4+x$*3T+_<9Rs=HB0PmRls>nd)zp=73}CZ^=hu!=s!0~qys zBjNd&aO*cgmJ{#xhJq}MaceS%>qcc>w*wd>hj-1gX3jIAVVZ|4GQ`1fIEV~7C%mNBYFdfSlfftQ zim5Hg>s_`hvb3C0aTn~vfMa?30^QN=&J4*~ysx4MvjT-3`fYoKOxlKJ8_t)Ti*WC< zWJ$Q>G1JZ1WIt|D-?SDGY_Nly4mN6=ELWTFPsg;Q6`$VGs%{f2m=g$X#Ztg@bZzXu z1yT@@??g$~c0kskp<)qF3BRmW>N+2TQ!Mwr3RiZ*lI){?`DMv6biY2ACF_3GWUclq zs58AAE{t2#^Hwt0imFD znmesL;hV~NAEjH=@NwNA?|lh1-unvse?#}ruH_-Q@1lfg)rAgp<1qIQc@{W=qm-o1 zF&rlzn-(XVxP7h+1meGYe6@aa`mW;7Gf6tH?EQdC7aK^+HRi4|$j*_Y{y&hJ?Y#LCIo@%rb9@bxYnT>mD6A`-zd%8<+v0NZ z$c>_p9;BF?6fW~gyNXM!iUD@vAjWV7cepc&>uksyxQ}6ch7mkL7CLTXi5g!qj<2~s z=lTuzzGc&YN2?z&?xLqW9^Pha1rPYof{c3w5Ams+%N3$NqED^(9*+@+pEm&4(Edi2 zj{>0}sX$XuRQOg>(%D)ci^40EU;i1r z9dDq*g!m_znF0lqg0e0oCy3P7ZGGFfo*6>ih8Qe-%3--T(jq literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/log/Logger.class b/target/classes/org/stefan/snrpc/log/Logger.class new file mode 100644 index 0000000000000000000000000000000000000000..b5e2ad002ea87a2129cb16dc4d868fca5efeb895 GIT binary patch literal 627 zcmb7>!A=4(6h&_l7zIHX23`0Ag9|5ycVodf&@^Kfhn!0EW2mP+_>#Mn+jK7FBw8*Y@HLKvfs)dkOa%FvkTm6?fAlG==$os$0r7x%;JBT%Z_f(O{{Uhz Bk?jBg literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/log/LoggerFactory.class b/target/classes/org/stefan/snrpc/log/LoggerFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..1310bd53d901ad74543bc53c4eb947b0cb5cc3ce GIT binary patch literal 4939 zcma)9ZFm${6@DkXVK&PIk|lhk&~^xvgw0ohR%wz3!e`SaA&?MQ5OlJc><(;Z*4bH7 zP}|yq--^~+6}5h$@dKqmNdl2lYbmvA)nEScuRf2DkNw~0@e$uUvmcWX2!!3abMHOp zyyu+voO}1(|6P3@zy|zPMu~(P%T6?B9DP_bn=_`JjyI>QM01ywNa*$sE$&$MaT!4g z6-TsVT60P>6V1B@kLYnnLdY;Pj%LPn39Gy2R?{k>EH9A}BCf`)W2BnnmKo35wr)Dj zTMNT(EiFX)jD)EIRxKF_XEEJ;^3Q94L znz{^A@5zn~>UO^XAR*Fa#kJIcW*g!?H(5?i@uN&i?tNaH3oncSY80rbl(AaEnmLmC zgqBHCM;NP6BS6$DkP)JHPSPOCpwJoSd<`?7&>fG55+1Jeh1&JEb?se)D`CTJB5l$3 zIiy5*n-x5abrNKn@6kpWj;gw~KI=JB36L8U)Z-Be>-?s2>vO>?ji@P93~*jEYF#@pAG@$yMlZQD2M5VN z1$)rPqF|26S--P+eLm#5DH(euEWb;i6G7RhV7~~;0>K`Av@_QsWw500D|)>rYdXe= z?#s_dnD$=VV!e&1ly%s+R4)!;#Bf-+{!s~0Kh#`AeMtM0wlykhHWv>~!64!i=BKkx z=Wxehh87+-!TQ2B8SLl&U8$6w&{7@oxSq-Qb}={}dEDcp zGq=l5WJee{-@aoK>Wen>heM}%jD1rW?$>PQupl5B-O~!@LlG1?q2Lp!^eEyxPr~>V zo|W+oLwLJt-#!J;;nPehwm9p~N=1z*CKiJieA*V8=sj?XB+Lia4j zAU7p?^JxWN#n;%Ihb`Od%@6sxJd3c`Qp*VG>k3}NH%KhqCK+e>if z={F@TooRYY)<_NM>`mV$_4aAD$=YmD)i7R0yZHL9g74uK)_|5y>n6|d#yLQFICE-S zL-+x6?l$9LD{Bs^qe&yBtKuXyw3Kmz)&&O~5&;;3wh$3pti& zD2y@uT*lAxwL9Hu1-}p-UrviSq|7kR;ny;LHT_7j+&Gd2I|M?vRVz3zSiI1cbMFTI zwif3N<${pEIIZ4X=^o4Rr1OW8$mnaL7%q#`+D}L?YyML=Ut_*PVBjWrGfb0!(yU}tDh2eXdaDGupc zM-Aak3FX5EsbQHsuB}m?)stwKaf7$iJ9v^0GP^7ffU>x_BYGvH`Z`6=EQw|Ft?_M{ zJ$Kv`xjkbNR{A8TMK+Izf+hNT@wI^$C*N+@&OKb2!+loPj_W&EBkoPr_d}&g!~!eX zV*~t!6GT{Ca5;*IJ0@q#I41lS0=S>wLLI2E0_AvsBk}eiKcy&9Hq%cY+#C?a%LL?^H^I)zoS z2|RQeYlN~ASJ?s=d4$*(5mA+^P#~oY>ReyK;`+rIfpCj!45++_emtaN zW+UH(=0|c!_vbvXj=DG>i$z)|@c8vfY$kL@V@uJ5a2^a=kcnKtp9z&%?K4-6?byL} z5n z8D!l&zrc49>>9>qlrAz6$Ai}phz08Vy2V_>I6lb;^fVUJv&4?#M4|E{TnywBIG+=|4S5MHIh!lk_ai5}BA=PW=eir-#^HuZ ze5GrQiMogvr|@zt@~sJ+A++yAzAwIh$ggqycpN`%9LFyyIfnXs+4?HC(%Y(7Ad>1M z6)1h_GDgQ>_XIfI5{%YY2lI1>TY|S)A1@d#sA(yUMow0j=B4UdN~bUxb3tDv=*Y=& z{3dc;p#H5VJb~X`zd*0cnUKXidc|`ykI*Ee@(kX>vp9_x`8-bN`_x z!SXce0lc3hLjeEA+r%T9@IP>qHC#fpwY2jNz36a9zvsy2`t#HsAQqFWf8gj8i7V!U z#1z9HITs|F`R-gP=U3rRoGUG~AkWr&v?aPkFXUScZNM#*D%Ogql5ll gv|bU3HBN|S&OVCLf&?e>3m>o>N%%AMmf$b{2jD*vLjV8( literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/log/SunLogger.class b/target/classes/org/stefan/snrpc/log/SunLogger.class new file mode 100644 index 0000000000000000000000000000000000000000..3890ca679acee8e1b8b3e0f916b88f53baaaa571 GIT binary patch literal 3438 zcmb_e-E$jP75`mX@=D4&HIAKDO`0gR8vK#iG)-JArwOtnIc^j=SdLvM&}1#GGCYMDW_V(TzkuO|2j2TY_?=zJk{h`*Flc7? z>fU?K?|h%LfByIH?f`fKztZ4Q*i$IxhD&90$;c0v^2OE6uwBRvrz`nnA(u0Y8oUa< zEoowlrE<~8lwCrFK&j58@Nn{yam5&}lr3BEa#lV!?9z=X^hMJ1Q?nB%FU-cqlko__ zBd!7wM}Y_#B1!X#X)AcnPbst?wenW^m_kpV3u_yMOP7m89qXS{@JB0Mi)L}wShP)ru4Ex& z*mFkFl6~#aTVA$G3gKi+cW$_x9`fdm6$i!9zu8=c?N;f8xmd}?^8%e!XzS}g7rhf);sYYYYOl5;w3XvZa$e^E*7qeE{wV059|1d z;J2sabMcvYkO4WQL&FoavakRAQ~*ctq=pe@V@roSB6WNeqYA!6Y&Mou*!@A;1qnE& z<0zg|&@U6Lqxt*i33FHK}2|9*w2|j#n%@YZm=Dp|JC8e%Z)p z8N@Js6Sl>d(Qr737&_!NspBLh|BcmEGtWpLY);XdgZi6%=9WZF#F!taXnJ_5Pz;xs zO|G_GxXO|Vub8Ehkz>Kca9Tv9-iKVTtSym+^NfyY$QMsb6Aj4XWr5MbF%-0j!)uQ<{?WuT{be8XW5%rLt&=E zCh+=I+%{Lte3=Sf#G(d+W!w-oVH>5Aj*M8S5i!Mj48lZC!;-?T24O=~4Nu3iFzIA+ zKwQpCur*v(=xpYc{-t9Dd4|}0u43414x3tBJ;dik^s0{M1X&C`ZI+h{Sr@v5GaAa9 zpj|$xw{;C~@{!Y7|I3q&=rD33`qLu%GYT{RZ<#Lq=Om{-uQ2gH z!Z)kS`ge+tv98sIbnr%~YH?6dOsJlwiv|coSaKQ)i5QGF4m8fz56(Ph3BxkO(3_=l zp{Vdk6ZCzF#j&6nc19ADGAur94IK{IX=BwHF&g|DUY5!9U1@}VX;`o7_&$C>^{yB; z%=C<$T$lDfD*t}2;}>%0mCmQ( zb#|SG?^1E8xkJuqw;P1Jn?WqbG8DVL9v7< zKHhM+^SzC`r%B=Ax_w~qCiH>9TiE_vbieIz?v!%}rITDc(1C6|$g`a;2OdI*JE3_P zyNJiOk4I{_M@XZ1w{75EbgyGi6_Hmf6!j$G|>z;u_a2F8z?tsweaK=ihRIDmt$ z7M{OTR1i>;>lli9Z{hL5KOwM=!)x#kRuLU~lWI)y5p{fg_VMZG^EjVTJ~3(@^{yeY zj(%B>t>c)iBM#mghHC46XBAUJ-rI;RbWPkuoDvdUPgjwwV!Dd-ZOkp)#4}M}$XCVr zXuFDPU2Rodi2B<`0&5rzwf6)LRgn$(tFT_f{+@vMVyOMj>)0(f-iwE#T1ac$3;#<2 z)e~@N{2}e`y+87WqX+L|kE@AGPM*SnDvAfIsI1|5tE(zLwT8#Y*zMld$UnP=&c*>v zkhExXBKRBTEO3ZUJItgy%;7(Rr|={v_bB3sau^=PX`Y>umw-z zc~ZQ{^-Dp4#anm#vd??yX5{Wr_$ee{trBhf8qlEMU?kAXS}$m zG%TthGO7nzwTJ6Ij+F>Kfk0SMfC#)OEaxuQQYVtlR{?LFxd$MOl~8 zbx$f!164etp`?Lhc(3ffeUJC|U3hpw%7`YvNAHm|_�-;X4{kjW*Hup7)^l?(}r) zoqqXPb2A=)q4JW=^XqtJ;V!&y&ELZJ?)*M@YG57LnDX9f=Kef4uW_T*H;1|L*Ec`q z##i6`jGK0Mv+xdHd5eDNWZCb=4c6&?7RwC`Q1}Q}iT(uF6O88>u5PBdwchSTfF5?d b(}!&*9Y^eN93rn9IMw1sQ{Ett2fzFeu}(iN literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/AbstractProtostuffSerializer.class b/target/classes/org/stefan/snrpc/serializer/AbstractProtostuffSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..bec8b383dcfb713e8d37edf714654aa48e3e6ddf GIT binary patch literal 3559 zcmb7GTXz#x6#h;!>69=9q^45j(xTGb${-Mgq!yacLZGzRgaTH@Npf0-PG`c*1So&V z<(t0HE_Atkb1naYKSq~(&g4oi4G&3XPWJxx{`U3!{olJk09?i!83BfCmc6AqF5lEl z)iLdAS#`LrYli-Y+v-Beac!;aKCms-2D+-_+wjLhk#?#?p=qp@`cDQ8u97(t9FID|06(PiD_E47^x zw~JcI;0(u?t+HmUYebFS>xYv2Om`U4%Y*zK6oU-I;a9fqa-TfI)97;9+EFXJwW@7- z@lffv9y*nr+UAukMUmT?<@Y0(8K7AxKjS-ECYEP7RM59f&8^u)YJ0Aj?#7uP+J|EC zV54&+G%qY4u4=Z^WO_Zik?poU1P993VjsUZvLE0P;fz&ynKHk|U(~qcGAu-Wk914T zo7I|IaBZ&bWMTvJTQJwEUg;gEs`!R!KIMWSnIf7rFJk zSZ(`bnjzW+<}~|BZFeM$DU5}|@VSC7aGomOr^=A&&9OTbvF;SWM{|>JR z-sVotpo&O*fQQ7pQBMut*_L-7Tu^o1GOjYjhRC}wA4UpeRN0LT)GIsJa-@UmF!Tfj z#h*d88=Vp#UXkHapLXpXeQIGZ*Ymh3;|9ZY7xkK}8>&AAa~cgc1q;a1VB6xZf65S# z#s*B1jyW2}EiB1c>}$!NopnpMamTmhpE9KCffXw(XK0Q?4{cK+jU}jPux;a#S1D_T3?l=nqllR zoa(KxkPm(g!1z6a%3dI;bMeUFI4aU7**#TURad<006 z*9CO)v5<|>J2~8ZKS58EI7uj<3X}j&;fyeJ3lg0I$Kr|KF!f{)=l1Z~pP2eZ;IwSU zh0O_H*0eXJ&C_wn$N z7gtFXNSrDNv>zngpvc`M=mjc_EF#E}!P}IqJLJS&isU`v_PlSj8TS-6>TyruJA6-0 zOBDYf@RS^vN%Kc&bP~lFN+?t1R>+!Ph@Lzr`Au;W_!kiw>oT@R>5Oh!J&5aq_|Jsr z5ud4ZTuJQX`Bf<*{XUuwB_>0`h_nwgJ{d~RzJ;Ci(i#+0PYShFjAD)6ixka=IE_bS v>~R~lnI^RvxT03c6l#LnD9#E(9^RxNBoWFuUgA{;HBa87#_*b~2eA7;j|!$X literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/ClientSerializer.class b/target/classes/org/stefan/snrpc/serializer/ClientSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..c8dec47a8319386d51c495a22d17873906ed3630 GIT binary patch literal 443 zcma)&!Ab)$7=$OQZnWB3D87RQX$~IuW>F9d3tjLY)8CS^CNas1_-Gz{03S+BE8Rr} z>2W6WPd?`3^X(nLC59Xs!-e%r5h6WEBZBcxi9lYRcmnUGYnVqS&CYk zr6})Lq$0y$LCP*@PQh6dh~esdwn=F#ZjEbV6+OwvVm$lrx5~_&+IAESz3Uf6F6vat zal|nBb4=TS=os50j$?*Vi&3@@41F@+yiW~<#6RtD%O-ZbyWnmrit%0It!(2J-RL?k paQ1t<$(kf*VAxCZ16i8#0D00psT>&&(M#S5`aiv-2J1XdzW{57gVX>3 literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/ProtobufSerializer.class b/target/classes/org/stefan/snrpc/serializer/ProtobufSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..7a5bcba28a41be7f04599a4ecb6b242ca0a8d739 GIT binary patch literal 1553 zcmb7ETTc@~6#k|c7TO{T3gQJ2QMTMx;YDpjLJ1^Inqt!0#PDFI%TN}!yUpxWgTKiK zFAo?^`~m(b zI^14e z+uW^j%9Hlmm_i(Bil+{ofTA^oDtdw9o=xtnX7>70(;uXx#7_NC*oxtuS+f16wRhZZ zNk24M^i{qtk45^9#9o0aC1kF2$lr6z;|zwbP}QfV(TGv*6rxYA z7pg=Uzf;=L-c0E<(3N4B?Gv$6J%;g%^KjgXW`c%{l4O{_GDcJknwu7vLAU8I&D}z; zxGRI@!ol9Uq=mbMYc!`8HfJ$|C73iIO(7d%Tl!6gWc^qPn)BFhfi9I2&6dj*4Nj`! zx1}w%o$!`SoObQ(_OFD)iAQv~;`9q)6rFAut&$joK@YLeZV@qh1L>b&Z%>f=hT$)? zjbVh|1LOn@8;oWz+)5kJj^AK*ucFKtXw zLEH@7H}~ClxbGjYZvZYaOb`iNlx`_~pa*58x31FClQXI?FXUuSZcUEgc939SV7O9i zB@1PjGMleR2Z8>Abh)4zJ=Nq{U!6}kCR55gTh$>Cj?`m1p8k2v&MMtTqyoL0XH8Ww zrS%Dp1SY?B>C4b?wuIeMf@6VEN0D_O0t2#JT3>NE30&`RvpVc}|AV{DNXPd~oR_uJ sbZZLEJp0+*q+y8#1opUoAmS*L5YN{geCRbIP>Hb@{8!Alu z(f2Q&D9mq9zT2Vi4SM%!(Cs@xuPD&(83J%z&K;VZX-Jmw6{U{>MGwl{Eh4-fVk%GvJ|WPW?tb^3b_ zQ{{TRSqR^FjA3oRZ%r6_r+Je3LQW-?GyJ-f(8vrw zC)acQ{wyV%g=Q;R%vgAHJe#&%Y-X4WmIRKCDT0*KSZV^4v^(xFzDR|sa2SzH;kLrF zxJx$7AAVdhVDSd#|;mnqadADJR@q9D$4qG>%+ z(R!qw^++{yoaG6&Du2&#wa!s-ELy+g?62Bvp1&2k0TxieBF=GUL`FEzJ#aq5{m8*j zIxtWd2iA=vRIQaG)U4GbG^|?T2ul;Mbq#cZUh8bK1|cre`x0tc)=_RV1$r7sk(s0- zcy(z{%_Jw~!I3>lsGw;sjcIMHDN)|gs=!j-&go61#fedlSS({n7?q6gA_bU z)6(J6#lA|M=5ccW`fkxARCz=t!$858f23o4^IIRLCIBExG}D7@@g7skVlyyD_G6CnnoIA ziy)t$0wQ`AkTtE1v__WFAYW#J+{DLOAc^LSG_p&Or>B63SOw%(d^J5uv-lZ@A literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/SnRpcRequestDecoder.class b/target/classes/org/stefan/snrpc/serializer/SnRpcRequestDecoder.class new file mode 100644 index 0000000000000000000000000000000000000000..5687ae761a066e2a20bcb0b35725706c275f07cb GIT binary patch literal 1615 zcmb7F>rN9v6#k|cR<>JEZbAhV_f&$(I3aYuoVVOcsIWJ{HbZgU}y^?k$670E%Gn0nqZ z4!OP~*M=8^dJ&dkDb+D6caFG|K8F!!=-IGrOKdW%gu8Q%WEgx2LZ!lsfCdE`gEt(> z^n#&JgC9K%{VB`lud0Vx?z}OwMb0pgDw#$xV-OQ0H#U7@->MLV&Inp5llX}i0>SXf z#ox@GN#xnQs3+X#u1jU2WD8ys@p`fj=B)G*VzMZ z3PPp6sF}Phtdd<(aFb#1!sc8Pz!+{R2rMCE^m@Xd-b1lYgnIexOw+mvQfh8F{mi>Pqx+oFlRUG$LVTg7^ zN-!-9^ZiSs+!#qUU8*`J-?8M-j<&h3mSjs~iiX`wmmUqaoOpWk(7S?bwDyv;L$ZgS zYV?%;3*Qj@Qn%@+wXg0u03Qa)b_myLZ^X664T>j!YCS4-E!hl_ZkYCb6nmr|{WnEW zXeSXn!ziWw3_m-Gkub?{hA9u$e6D8Lr@X5xe_-})>=g6s{^(Z($NXoAda&Lz)^kE( zypXV_2|Q?WRD>XhE`$lpV-gV>uvI$n7FkHByKd@ps0l1%g`g1}+#^eQ>;&%P0mTiG m_Zl7&^i}eGgvWHOE!tm4oJiXsOZsGJe=ttP#}g7g*!&0E)wpi} literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/SnRpcRequestEncoder.class b/target/classes/org/stefan/snrpc/serializer/SnRpcRequestEncoder.class new file mode 100644 index 0000000000000000000000000000000000000000..6abaced7fac7b86e86eea615479126ebf4b6dba8 GIT binary patch literal 1816 zcmb_cYflqV5IwgotSkjY5P84BwmepR0!4&YP_#lqO{3w{c6))vvRij=dH9d~Xrcm| z7(e@?jI$3)fdZP?q}#o>GiT1soS9$0zx@Dk4=*JI7!=dmP;9~1RYS22tDq@1w{$hH zf8dsqHdYJTDt}+(wpcJUGsi6nA%;=MX)9~mwqkH0_7!bYH4L6t()xBG&y(KixoYI{ z++vVVAQ{F}mqkqGb#91si9(#AdPX;NG0QL!`8U^Sh9Q(B(lUam4MRehAsC5fYQRt* zMir_V8dAE!my6q3ZoO8sdCqVnWol|Zqf!;<>|ch&rfw63OBqxs7xAy(wRFM#D)Jn| z8!wMa^*dd;q-hAgC*p3^9nVeq0hmg9!ei7rCk;KILVXpTfvC&(+=Ev|{UgdT>-Wz8+GkAyykE*C^M zmBhZ_^OmLVuM|b0DAK~>>b8tt3^;8Yq&`NLqM2F@BO>9pFTjgbdsahXL=j`Coj40 z!xQew4%1lPC#JiWS}5?GcgqlqtR_W?P(v+SEQ+E&QdrY zTAzbw8kaGR83`oZ-YXo4?qkqgR=EOac=z9QeVWmEsX0;)YGRMp*Hu~hOXzr%7#LM! z_(HF8eH%Ugcb1J~uRWI@f(swQoVo|3>y!Z@Wg+HGDFD>16rUYf(SS+q31s5`5w zwOo$=f*yBf3VpQVg0$voojH4s-U9S4;Tk<_=(I@Z0R76b1Nx49LER_Urh%UIu4fZM zXeQg6xK4L1o;4Z?&-utMDpeCrWECJQkUb+i2mK=5S6Wz<-(fhV>4hQI; z4#hsBt}QfngrOkXLSHd*2xYozgp40Bv{fBq>V!hKKDDG7!pvJK$HAI3ohyZ`_I literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/SnRpcResponse.class b/target/classes/org/stefan/snrpc/serializer/SnRpcResponse.class new file mode 100644 index 0000000000000000000000000000000000000000..b288b07bdf967c38069d1ac33ee7b05a3ab93df0 GIT binary patch literal 1478 zcma)*Z*S626vm$m3k2`Bqpd47LvtR9p14nti`sd(fFM- z(P&Kc1Nfng=d`sgj3vJ5?JduJ?(aP3@cYk?UjSOTl|oFQW?DnlcI2UEsJ3B^2dXVC zT^s4|rKR?a?s(9Z_SiIRnL8sUyu8s?QIO<-ie0Tk`cp+Rl?l0@+UZd(W|S zV|bqg^4&m=9o;kpauLDak!8Ns4n~qRNlV(35xGSjyc_t}2fCp(CmJJsj(<^-uRe@^I@q6VDA9u=L@4WY**SyW3j-3=50$Zmd zpE&wReJX8R8_Kq6ooJ3DEd@8wq<$Z|9|Z13YxKi^8A&-S({;ldgCi{q05qsk|UQqU0ZOS@}Amv;+q(gAqrUcJymzl zP+ySyMCLIt6w82(xj+{Kpj{s*IRoRBv`N>MA|S~CBpHBg;L;qB;w(sIF32X?d&x|J z6vI?JkS)4y`wS3n7$;J8+sP?M6RFIC)aQa+!}WO}m06G`fv9JI@We34R?wOkq~}wEj#`N5&A@G{=nlo&ilCN)X;R5BhMRu@FnJC# literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/SnRpcResponseDecoder.class b/target/classes/org/stefan/snrpc/serializer/SnRpcResponseDecoder.class new file mode 100644 index 0000000000000000000000000000000000000000..ad89e1af0d8a9add901a2b1287931509dbcd4eda GIT binary patch literal 1626 zcmb7F>rN9v7(LS#7RrL+m4c`sU<;O2QB>-MP$e`$O{i(&KeyXySuE3LI~ed0d<>re z6AeKVAHbhJk1?LEy+f`rW*38^lBv;SctW}R*JPo!%d~pivnl=+3aY#kidY2et{8FwB1M!N@U{_1_inU>6Q$4a~oQcG*X^3 zk*?UdYV=)3FN2&a$#o+iws8$3s?j0rf$Nt;vkHJ#Utx*EqQlBUur zfz*Ds4+5P@6}m8iw1pc2H%`)zT#*e%XK#!0v$o?b`h9p zx*zK*BH-@4cD=XH-Fj;_3fbsBB;A&rx@tvKV7u zXh#3Z2o@#T^fvmK_9NQFW}2JJ0^1mhU^*6R&d01bP31R?zD{r9`b^vSXLKjpwlN;T zOnahzlVPGTu!ad9=ws>xYz&~E6L=kiNZ|^v`Ky@ap$*i9F!c`9ENxc&5=#yvuxqVIh?;IU>YpFxJCJ)|YS9`-L>V*T-m+Xx>20o4<{rvLx| literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/serializer/SnRpcResponseEncoder.class b/target/classes/org/stefan/snrpc/serializer/SnRpcResponseEncoder.class new file mode 100644 index 0000000000000000000000000000000000000000..945c07938c47e82ae739eb0615682e78b07d6782 GIT binary patch literal 1824 zcmb_cYg5xu5IwgoMnVfJit-Y~S3@fSd_onWSVXNlLmfuPPicCo!IH$ATOR%+KRV+B zbjI!=;1z*oYfPANmQo%w_GG;dD~V?;t-fE^||66bvwEhjzEIKngA} z^am)Gqh~iHpAo{?cwUumRTiY+#)^tTT=W}vi8`5lq%F4L3X%%0)+BhKaQCPv4h_T9 z2p(v7ThR;;l3^AUzcFlB?*qXblc1veB-3$R!w5s0bn1!tl(pAc6{8qeFvf6sZ?%in zr6n4(TF;S=Rvfo+hoP0aHdmEZLBiIk zX?rPb4{nV^Xqr(miMt9&yMsqK5Z!yA*=z|k&hYlXNqaY={c7{o9yR4UgML(2wMDc& zO$>~xapgd-M)6Y#j*Hp`WJm=*ecU0jDD@a2B=8XPlmx>gvW?*JA2HMjJOBUy literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/server/ParseXmlToService.class b/target/classes/org/stefan/snrpc/server/ParseXmlToService.class new file mode 100644 index 0000000000000000000000000000000000000000..121590e6afe3e25970e181394134c55b42ccdc8e GIT binary patch literal 1470 zcma)6+foxj5Iqx;3?|DhB$42Si(C={tQQm|h!+&W3ehqYrM@l85EjF3YIj1(ulNH# z`y!xKmd}2IU*K1Wy%)d`D1DjT>7G7)ru+2#`2FP@fLnOZ5n{+$c13lh*w9SXG3}bJ zI>O!&w)#@D9r1d*x?+{dVCaG)%+R@|?PzLMGb`$gwJo7bhUlze8gh=IC7WAi2+v#V zB8C=RP!K_sp`&P+qEz2r6ZVR>Ruv41qNQuqRn0cseP9gBO~YZx7yp}3fgw_JS;o+b z1VCdPr=thzuUJ-K1bfjkLL})mhYfgJQvf!pkE4YXrhAxV) z*;Y;1(h$yq;a)3AC@1A9OWQCj1&&^Z(X(k$b$wEGTX^M;A%n|q*{(38vdv(*)j0Yv zz|qezbT(!qpn^eMV^F*@1%0IY9}%rfqpB7SM;783#wf=KL%Vl{V~>I?aty786t*TU zn<3p0y%g99A&&`;ae_ZVIPxl(gi6{l#d}grW1)NRv!TM#8<#F~y)Z z9SwwAHcLXv-5^HTi<-G!6}Eyqm}ZF8>hib{!`XA%ev+`@);y1U3T8lp`p!rzGeQ0F8qR|n;wx#R~r}ry%zKc0U`RM zSAtefJC(kSzLBv#w0`p3FCe_{K#G)a8+LCb`kv=j$_#@6 z|8c5|l3?F}fSM#U-LxD_j4`Yx>sNdh6@4oVjcK>QTfoq+K|!;8JFlSys)`soG_>MP zhFDUPwr43Svz4tp_m+&j%^4C|*EH-E!?WZ*I&75T+IP0TY>~6AMK1Ou&oGeeJJFGv zG!d^l@yz69VY!a4;1WZ}VcrjJRCJ+7K{rG9Df#y`ypM|v&E*IPDthsef)5#z_2ys0 z6(mW7VVc|zurqgt9EQHX5<1g$)(Pf>@HD+y#gvME3@R94=y}bkT4D_!V~C-RLcGY0 z!jiSc-HHg(nrQ|BTM^-rf)R$1+W1ge6l|)ph)6#oV=BCo5&A^Kr?`IT^Dx8InSDN5 z8x>*My0q0xwcrN6Q1Cg!r69Gz6?th^JdZmfpjxI{(U8JT25lyj&1P~F>ABgvIfkz6 z|1wc1hcPCRev9E&Xz~emOrIjDZ>1IENGrI*aHTekQ7_o9@_n#txQhu&fl(-A4WF_y znhdoBeJdwC%PFQ#D~2c!slJtF+#_KHZcA|lG^l|qpw@N0HW~YvmSHmWk`QHmiXQ1w#n~J`;Ef>; zs946TH0J?z%Vb7|_z{JeJ5h+AFkG!8#D1CD6Q2mVR6NE)GYl%10$;ZcA#-Ii+^E-1 z*AWE#w7XUIsKL0Niaa`+u}+3Xt|=&;ko)5%W(1%XD&!3fo3JU5ksyD@pxM=a1p0J9 zNh-pTQE?f@BE$w|DKAfi>oIdqPL{JY`&RF03u6TEb2(v{o1`}yKx)pdcqX5;86&l^1qqkAo$7pTuA9#tj{=t`s_g9hlH6Xk|Pc>j5v|1_b|K~ zo?h$x?l*i^#poZn9m7Ckat~9hyO^$GK03+mVR<$2RTcN6gNJ)~9Flw;oviI4zgk5h z+VVXV1Mx3lk(PKBTj9+wWKj&#r)ebUd7mtPK%P8A2Ogn^(B4Pu5Y}i$7}TWKaGLyIb}G3gGyjbhS>A80t2DH`qg7Eg(z0Y2%Y&z65Mq+nd; YM$kb6D%hsAkpTS-36;TS^dJ2F2S0=X-v9sr literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/server/SnNettyRpcServer.class b/target/classes/org/stefan/snrpc/server/SnNettyRpcServer.class new file mode 100644 index 0000000000000000000000000000000000000000..4a85a75812290c7614c23dd9a808c101f1d1c6d1 GIT binary patch literal 6544 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 heV|45uzT=-tLm|$5{sB8iIkx}+ literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/server/StatisticsService.class b/target/classes/org/stefan/snrpc/server/StatisticsService.class new file mode 100644 index 0000000000000000000000000000000000000000..c023a2530c2db6a569e5bbdb62096e706e7f546e GIT binary patch literal 2955 zcmbtW`&Sc36#hm63G1pD9)c(YM9M=9sMQvzt&bwufJi8cR@-GWz-qD^HybMUVb#9h zkAI^-w0KVNlymwA^pEQ4H@g7>p&omhoHKVabMKvdzx&Od{Pp)Ae*!p(U&7cW(CxSj z@th~;4LhE*-K-hUNq0%Q@uX*XR?f4`T#^fxDZ>Z})Z8(ajCk6x7vfju?nu)Us7gBv z3(^%hoGA0ft$4!U9um-9c`q+>-n5mGIf1T(?A30GX5MwB?Zpkx$yjFmoG%iN zy+F%dsd<4zfxaj2d-0@|$)@E+!;>S9n=w4kN2fgvC+}NOlB~b({LE=%Iguv zRGLWAb1eefJ);ges-qg3z`lfK%ZYquPP)^^Tv`f56OL)5XAIX;zx_oG6=)*1-lD}4 z_Lf8OZ|q@(qOQz3u6JI}JFXnFmz=viqpxd6AC{4}9w-*tQ(1E=;LT9?4UO?0*AYiQ z3!ZYOe24$h38@h-GEt!C#ZOl?I;G=foF-PJ$T>STW}B|ekhMPNE{E}oz=6#h62N>u zZ>3YxjbKoqRm-V_V#V_*6(X^|;wPrz4BEqZO#6aGoq7h$Oy1 zN9jFMswC+45QdcBi#p!K2rZ3lR@x~awKBzW+hX`b5sV7NHbPwwd8^bkTt*^{w|KqF z?i;DGQ(1M4V}jj*kop&F!pM*pbzSA5FpbNY)Nxhm@1g#<^cJ0zGEh579nGp-S~V=(4dc$1PM%!m z1CY^?MutRo@?=$gfQ#kCC)p}IGFciKpGJ<3tU@{BIRU>lxbVUtp0z%mw%X{(tM*fw zRc`3rv$6tBC8%$?B5R7TJZ*aMnW7jM!S`CRGa&oFiu1!kUzd5#g z&_3A$!}KDPOoj27jcq6L?)WNp3}|?yuI590rdsXi>;R>$b}Db%s(Z58DxEKNe5IOv zWzI8P;t?@SQ|59V>}RcHeA%&E9?*5=0fCnF>#^gDpq|5`;}h(0>$)%U)M`m5@0xPN zQV&2w*`I*psvx`!W40|_|GLT?+SrvV_@APJ`Sao9?4WwLe95PUGQ#g}=+xW8U)OwX zpfxIWD|=SawdtzLU##&>lqwa_jULKI^x_y-RD`D})m~N4GxUXi zA<aCdIK}dW)hjn7&KVR9SJN03(_TmgbdM z!D4R#b^-S`lb=EzLuw_OF_xo^sm4%)c0Ma@oE_n;9Y;CqL2jGrLV_e4(4{xy;OWF5fwS|NZ_0;0<8Rd@{8lAm9Lv&(unV^Bi6iv)Cw0g?O zkLA@sx(hMTl3}Gn_JvcypBzShtO|zR-VF5|Fr*==61p#RNg=zPycA#cJ@+c zo|E>r@YDyV3O>ucZs{PwG9JWOVR$(kBE>4!7#4)q)Ul^*uR3Qlr(;;9+HSe~GzisE z6%3mx?xV$!oZHf6^1TY=w5OPV9bgQL=W1kxFCASUPlcKq!{Mym9}#!0cP7)eP-gT& z`mxPpJY(3olXoKh%othj+{s-5& cLnRTms=yENsM3$|q&j^{a-04zp^%Qg8|{R@%K!iX literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/BufferCache.class b/target/classes/org/stefan/snrpc/util/BufferCache.class new file mode 100644 index 0000000000000000000000000000000000000000..c3cf2e7fef757fc6c9923fddd551a95da8814248 GIT binary patch literal 911 zcma)4+iuf95IvJLb>f)j(w0)L4ZV=~0Sob%s1l8cgs?y&Z4r+fXOp;f?aCJ<{)&s# zN+2Pg`6$Hf8VC=Sntj;WJv%e!%!t3C6+EVDS9Skg(y-Uk_)o6k|8?M9?KvhW<1Z zX%5B+qXP;7UO2}}KG z%nEN1wy!N@=ZOgmH4Al^gyo)2Q~{xBp@d~ZjrruO>}(|CLoo_ib5j>`EMi~XHE5!U z8WX28KVeq)T3XeHsZ8@K2zI-(XvHS(;GTiIg!L;MY~em0a3?rBVU6?7z4A}$8fX#r z7HhDHEo@uZ!6u>P1yaP^q>-KjLVHoo1alZ=u_p(tNIPryGyKmLE{r&3s~jd)Q?rRHLPh=CFF1Z z7fgHtO7a!H`Y4}A>k3sRpfinxhBZp=1W36j+L84MW zpdVFrc5MW-h?nuqnVsV^m*0PGe*t)peFqi7YMS+eT+1&a3GyTxM8Qz2IQXbydCrc5 zDxrBTzKI|fNiX=+y_S(COdP00=?{dlR{MfbJxs5pi!szajAMe(2vs7FhF`lfI}_bl z68tcYM0_DKW#SU7>b}YeYvJ=MIs~UDwGl=)H7JM3^>CcU@Fv4p16Pus+m~Z<# m=PJA*z~`4hjT!6AQezI+a?cg@Xk(Z22Hj)NNP25)-~9!`WVOWr literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/HandlerMapper.class b/target/classes/org/stefan/snrpc/util/HandlerMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..beb2ae6533f0714ddbf971b4946fb5280c861c1e GIT binary patch literal 2117 zcma)6&vz456#ib5W+szVAT(_QA}PO2(l$|`6`NXx3br*ZVz3wr>NJ_AgXv7pWWvFf z9uLQJbcM_6iWM6cx=B^esXG?_BmNiG@6DuS3LX!OdGp?V_t*E``|e-={ILVz9I6WX z1Wwvcz0h)vb=@koET>s5v|Y1NnAfdZ!*G`LX47yKgar=X(eLVohHljhSJ&|~6b$zX22qa2&Rd1~5jw#PwVc6X; zTLPy`FOf=7V4!Zez4Qc5WmZei=T^-6A`c5e&@5Uu>z3}e9j3AP5+*YNr)AeMt$Hya z@hK?I78M*8IMIv0&}bNSy>Zd0w>J&Ty?n1~G+ooSR3rtG8$PYAv}L>LreohVYer2& z0>hHB5o%-tLAqhHD+-PX9P)y6tJB&bDh(+_CE>^7cn!w|R8lk7&|75laHdOvS20gm z)G&&Z3Qn*xy@b81I8NcTPwj%`8qT_2HRxn8lMQm)^YVHe8Ds?%23*!RNhwud%v^)O zSRCV+V6%{ZTay2u5O2m%z?%x*U=lr?#2Cj}oMVSI+ibWCL3X+&2t@5lf{AoR3MK`H zd!T)0FSX4^&2Ut_C6L`@a%q*U2^s0vQ7?#U)97W6!nS3Nx zO<*FJ-d^zn`R$8ZRKb@cZc9(^#c@&6sk*kW!|h(Hu#~|XbO8xyT?KL^U)ny>*zQXA zTE4j+?w<8CKrC}27{D*GK))%QfNd8r-@6-lX6+Y07@~_?U}*na|Ejt7-Y54b`;rfh zE%tmSGr3tg56Z4y{gO0z<3z!nf&~Si?3-AAQYvl`mt-Ta;W{dD+?1WEwOrkCTQ^L1 zL&YuDQ)=AHtN4sFt<|=;`+^0j+M9WKqCweiJ5}R~>5a7c;HbP^Zaw}Db(D~ zPZ)TDL?tn}jiEoEAXVAM(NeB5-M=#x4$VG-o$5b!c4@qWS35{gM^cf>w6-%94Na+! zu#nP{>e*=}rF3v+I+lw4hTIk+k1#QoijDt{d=&jN_Mk0twnutX2bv>Kw8Z+VrLzSc*c7VrbqXmpo}MHGCj$bt!OfL&U|e362X zCsa`OZp-p^1o0Pc6^u&7vcg`YO7?#o^zD+N=R%S{4o+q$JLf)gmQ9k+C0084bPN6A z$GOC6Z+pA9{d{j5dQ6LuSBEq751in7k}RAi>u1PA2FID!D8`Uuta0Q6EtvNh1G$q8 P8jfk2oaQ=DeOUV!-(K&q literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/IOUtils.class b/target/classes/org/stefan/snrpc/util/IOUtils.class new file mode 100644 index 0000000000000000000000000000000000000000..0f82be317328a7b0b275113c4188499c85e7e0c1 GIT binary patch literal 2015 zcmaJ?TTdHD7(Ih`S!@G|5KMrQwp@}xp|~}169c)>R2Z|sCXN@`>)=RL z#qX&4(x<#sm3SfQMa^TSKJ~djrHV?=%&sqLtMV}O&3u=0zBAvN-~RgX7XZ_EVxUPN z<`fSSCD+=|780dG@hF!lyLLX2OmA{48PEj6PqQzwiF~$jkVx-7wQ{aN^SoWK-9>@G z$mo`Uw(RU#Ap{UKp`%&gLdq^!cgxRrt>Q*@H*X1arkq?hzm+Z8^6Xz~?x9^07)bpu zi8+B_(aP?vmh<_S0@0C_B4j&>WZ|gnW?VX-&uuRylafnlrINFbT-zy-eWyTIEjV5C z80Z$bQg16+*t06>vYXyta>|9hQY|oqE(Alkh<6P1HrA>Go9IJ7C6EjSj1k2nX&@%h zU4>pruQrs7A}G*g7X%{z*@=L@`_i>2Ow;xfwRZOROBO{JNgnc6;lMrQf$4gVZ0Tsr zxY^vZ_3V)^Ys+!bcCDmz_0`2>em-*U;R6`NytrKW`teKkewEs#6Bq1Gw2POEiBz|7^Hl69|a zTdsWno_fV)>5%g@H@ek|+gLJiN1&rBd(CZPSx%*{3K>|bzNDJzjl-gI> zt;bp!HrVZh7c4iCadOWrm(U@6f|P+zIrj>>?liHEyS%nbUh{`#ch5QI)A74`EYm(S zaZgffEBP)JCp{Sx8!|U+mwb`^25>yuQp~7?*F&8TI|yZ*axrJE z+VZP3{qKB2^2Q)YjK2*)GcA6|Tn(NQ+y!?%{u(W(G@20dgMc=)(l)&S?rl5;(T)p@ z3e(o;=}={US0#b@*f(hX30;p~Bl0FNtG&Xt_*gWe?ZhJ5-Whsk^@y$_qKvroCZa|3 zomnlS#lAiNL!t*1dR(o2tlv-681XKl69a7GGOlr*z!kj5yE$A{3>VoBu^DlhyR-)J zu3|mU$RVk#|ZuH(9E~c#an*yf3jW>qlo{jPnQ*BwaIvY zxcAEroPTwOG1}nh#B_# zPtAWO7g=jQeui1KEJ$lnF0)#H^dxo?(M}rFCgn;r9Ioud!Y!4Zh!&{qe8+rG^GoU- z7g%wT>ffSHw-Lb|D!N2{K2rQm{mLaoEMn7QuL(bSXGoCQ#3uf#xCxXds<;bQkl*F!e*>9Ri4On( literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/LRUMap.class b/target/classes/org/stefan/snrpc/util/LRUMap.class new file mode 100644 index 0000000000000000000000000000000000000000..efc7b231c8e5f81cd70b0f07a0ba6ef5a9810b29 GIT binary patch literal 2946 zcmb7GTUQ%Z6#h;Uk^)mMK`t%O(pqT}Xlbq1+N50MVgsSo0mn$jqF5_Wr(ozP-<0`Rm`8e*(CJy%<6Q z1I5zjnCr=BrZeU`rM<$~zGvBExhE@&COskoz1!x2S+-ivj@)=?x?6fPDsaBCNs~Z_ zD@&GX=Vi&Yiq1-QMnKHdZMx{Vp6Pgb)83a&|E&Gc{&M2`zXf8u=9f#>SCVd7foR5Z zEN@&OlE^0Wd`%ZOWMpCzXh9dcV|Y!VO*7i2vpKeCdRqp1&`ZyPv}_eOlbmTm7#9q* z;UW`gHL%QCqR2@IE0)D?TYzAX!0I_bkzo7iWK94V1PyKCT0+#%$Sq&V?L;Za{j z<()S0uJUdw*wQR9Dv``9`-FiE9wcXoHrBNBHgQ5e$(CNU+@S|~c6X*uqK;^}Ub zk@kPzzzk-2?jwKQ*9vLgz(cjubf7w&414<&;a&rz3jMpmhn)TKAP8V&PeZmPsn86daGWrBc^9=)Q zFa^#@b$N6?w`ziD%G931zfVC2`&n_ANR?H~QgOdjkaLzA4z2zuys2anSkElnKVGAKR5!4c@HDT<#wdrS`nT;UxL^VftBE+U3= z{BGum4{>US)Xd{|8*Oc9=d**WZA7>O45W9>ha@o8ADtVN%IKi0)7c?xs0oPU&HJCh42QyLm1ZlU-L_0 zcBOvD_0+HEe}P!!M?}I827aPBqG?s~Krc!AH06*V5>R$w1f!(tq~8tPO8%Az=~sL@1r z|A234*c{g?`)F$95O4onhkLb3!f0@wDBi(6@>Uqsp3lH>b{fO|dWP$-%)r4&ZY9Yq z-$#;+SGvG2$0&<)dNawT{`9U zM0;_r2MMg`1Xj5YS~Fi?-&tOgxf7206dw~^wWoi{j@pxLj;C1Fdz|V4-)EYyy7r&f zA9r3;{r?T)cn@ILkHHq|VIQ9nmeW3feRd3XvmSQ&Ot4{Clqkd@>raFo*j%eWV!IT# H7;XL!FMjXz literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/MessageFormatter.class b/target/classes/org/stefan/snrpc/util/MessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..695e1115687f9ad2e2b6ccf2ac7251a79c300408 GIT binary patch literal 6558 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 NqK>uyj(e(b?cYoenl}Id literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/SchemaCache.class b/target/classes/org/stefan/snrpc/util/SchemaCache.class new file mode 100644 index 0000000000000000000000000000000000000000..c05db8ba4a2a2234af1cbf82c79a0e2376458d51 GIT binary patch literal 3068 zcmb_e-%}G;6#gzGS%`~F%bjOdtC% z^tCfS_0_gB=(IDmQ)lQ*|Bp`p39bF^?h4B&k_TV*?mc_%Ip6o4bMM{1|NC_vz`HOM zv&1KE9jXQcxvub9etTpXQRV$Y78Y_BE=b#`U5V@y+rE68awye!A-80IzfLhE= zPt8o;%1v?bf~tJo6)?eWCCKpb|AoZ49w2bQKu#Bl1xC7kVZIae;x| ziXTQ2X$2_(ZD&`rS+grEhBoJpuFxv_a9E-{sY1g$MAv8%-PkM8`B?3YS0Grf>Z_{) z-9CS}ek?G*S(d9))c4&}iJfOT`%d6^E4A*~-h1~OZvP4N_+mS`-6{$U?;7@nXIIhI z%U^KkIxVdryX_2c0W07x+rQNirMqVRYj;}|;xBi+WpI;JE31a76>D>i@|^Ky)3EFo znvi|H`bGn0TSqsMQSgC4{H4QV2RdOM7wIr2F{R=XE(>(A->>Q>H-~MQJPTs+#0_74 zyk3%r#uXJG;v=46T;Y_B>TcUjFZxI^UFigptrHOlH+(SmzXAli*Kv`@+E!UTgaU=# zyQg(HQrB65*_P^RHR?6XXsuJeeX|i;Y84NkzXUKn$R)vWT!+J5eC)~v%c+*AUoR*K^>VPW1(u{V`r z`xWa=vus?d$a^#5yZTPbUgJH&)0clHf=4nhTaF56ZRp^v1D%i?YY#2sju)`^H>iu< z5j?`)Ul9Gt@jbw26ahXXe0DQJ1YI0s&Q}?mx3U*U<0xnkCLf_^Yq?C!;LZ}&bwDo; z(bg&N3IcLr^*dmm5sXYXom|6_{LhG{)^Oqv49}!D5KKR$VX^S1XZ{PZeewDt0>kE;%2h|d&` z;0&+pF${23pTlFok!%{LaGDW<$np2@47o+Np=Ux-dVMlMfbE=n~{rPqHzI=wg^S|1Izj|P53 z@1amEaJn$EfjuK@n5Of>cL5O##DWi=|C@TqtS;l@EI-ICgkdI#lW~G?Nit25M}jak zhh@^K#0BIrL;n!YJKSW`oIwGzgf+~I{whAE8j`Q9uIn|&H_4I_p0f`X1(W2dpa>!4 z6Wwjk>Dsld8m6Q39`)-R*h>Yjd;Iu%)3x06EIyunOd)^FL&V!f w?7c*JjI~G-n`~gWK52XoowE=Xk+l;(F4D5(ap^?cQ}mKXHw|SjXv6LQ0bO`5K>z>% literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/Sequence.class b/target/classes/org/stefan/snrpc/util/Sequence.class new file mode 100644 index 0000000000000000000000000000000000000000..338e65edaf1d3beba049922832df86394032e4b2 GIT binary patch literal 639 zcmaJ-!A{#i6r8n9oVa#_L!l`x5!@h$`ha=@^@6B`nzn}^ByQcfTQC?qbsW-<=_m98 z94ZwFq~^w#@DT`gc9RyVhwfqDzS)`g=DnNypH~3Z(Q;u4wDRI08kFj@%%VY7^y6q) zCTY}FUxq4+l?z8;_DG(}D3#ek^r3g8;!>cJ=JByA1R9-xKQ{!bgQ;9V>@eMo(_Y!(+Kk^Irp-`ItdPzZyPVR0ZmtBvbE)Cp}f{%3i8;(>#{x zo-7ibPeG?VOa=nWo&Qfndrqdlat3;#xu9Fh`1qadn=&q*3(P%?w0l_Oqe)Y*n-7av zy-Bo#;Ln0yYA#l2*XC9&ENb_BdD=Up&AY}-;1RP|WatxK!ruP@{{r>UzP&(rM$p0> zZ_iMwj5RzlC@AKZrX?aqL42l7{e!GxK-Wn82?6t1AhCw0XcE!=M=Y+zE9a>1zx{QN z(D}&jjNjlolUIBEy*<7rv4SPENN!=-MBDgVG~)%l>vT2Ch9S#0$O!)WeMXfJ>kds9 O_O{EV2)rO>Vd*!ao^+J} literal 0 HcmV?d00001 diff --git a/target/classes/org/stefan/snrpc/util/StringUtil.class b/target/classes/org/stefan/snrpc/util/StringUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..709fd4b39f3ce3b749284ab8bd3f7751912a2b82 GIT binary patch literal 680 zcmah{JyXI!5Pe4i0R)2x`27JDP?*9J$8pBdDq?|B*c~zAVMs8!IO9+87ueX?;EaW( zg+I!1Bg}wOP~6^bcK7Xjd-?i){{XO$iiQ}&uIG1+K-xFlH3HWkSVky?W3;3%-0mg0 z8dQc{k3Vq3;cnMB@APa-G9(U!E94=AQmwTa)MM}3PD4Q|gE$flx+z?{8TLE2f5AJB z&5$=ei#u)Zizps{ROPJ*7%JvG9t{Rf1SkE0d}JtA%?YCs*GBCsi6sW4v5caI!XMV7 znhZ)KQyN!3wvss0H)pQ{g%A7b?hn)(b?d7+Flg_fE^D`68`l;5V4fRa;= Y7$NV>M^*?~{g0fTgG_%U&55D>1BLp9u>b%7 literal 0 HcmV?d00001 diff --git a/target/classes/snrpcserver.properties b/target/classes/snrpcserver.properties new file mode 100644 index 0000000..e154b8f --- /dev/null +++ b/target/classes/snrpcserver.properties @@ -0,0 +1,10 @@ +#tcpNoDelay +snrpc.tcp.nodelay=true +#call the bind method as many times as you want +snrpc.tcp.reuseAddress=true +#ISDEBUG +snrpc.dev=true +#TCP timeout +snrpc.read.timeout=25000 +#server port +snrpc.http.port=8080 diff --git a/target/test-classes/config.xml b/target/test-classes/config.xml new file mode 100644 index 0000000..a4f9341 --- /dev/null +++ b/target/test-classes/config.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/target/test-classes/org/stefan/snrpc/Client.class b/target/test-classes/org/stefan/snrpc/Client.class new file mode 100644 index 0000000000000000000000000000000000000000..b20dbfafcc817fee0652899607b1b0e37e5249f4 GIT binary patch literal 1732 zcma)6ZBrXn6n<`4dc(352oU;$O{y(T%1cyARZ`J5ip3@=ZPF-Kow+QxVe4jZW_Lm9 zukc^^xqg6YnQ{E=f3kY+ZaM~%%$UsV-M#m`Jm=i!Ie)!*{Re;*{K%1Dm{oqW5QOrX z@Ct$Fx9vj7b)*+^7z`87#epce!fO^D?mU-v$Z+nC<2m6v!%!~YU@%H*SDF~Yh=pOC zV;Cs;7iwNrhT-Akwp~)5N5CEBZ3sJ5{$UbR3?r__w5Nj5!~|wE_Owpb zn`u+0y1;O2P^vAZTwPedTqb65Ne92ou$b$uwdVEnimH2uAwMW(Nwr$ai=Cr-P0ZmE zN0wo}$0v~ff%K^(lxouprTPq%k;~xWlhq_$NB<4p%ncPH?&33!X11{+7Ruw^mZAR`kD3=*TGTLAwIM4Iqotf zLlsxfFrDjeZl@n6O8AoF3x=tvtkVTs*w9FMTlc{AOx(xU9Gh>ABO%xKeD$*?tc3@W zU?byNDD0o=K2d{&C;TR9bE=Q-C^peY%ZTXtzxhm^iQ7#59^@49m{dP(yW+(QhCXWP z%VculolDcB=ImY5F{6??^f=uBIvb1Xu84LtmN+ULPZ@3u(8SqMLX@tleczTFjvjQQ z@#I|A7;qItO`5Yng5GE}(v#CyfmTNA@Xcc+Uq;6!J@qj#N`JtL4QL&suMwQbIPGZX zzhO`);K>Olwo|Fe%&*6oE}vj_d*PU7=?Uia%azJvD)S0g6ZjLE>Qd^)E94VcGk(X? z30AgKtH=20qH%<^Bdj0c-fu`&myYn&OG=VK84rmyL(rg>BRJ39TVjAmsTlVmkT zik`+QX2?E`EnGkymm}+SDun>jeudUCidChEI`VC@dqmw>px!)2jdHBgc&wAHK_>

=QR&YU?jbME~3`Sm-1XLu@+5Lh1Tfjte}6Xn}eUr!vn?dl6x zOPB(MGj*Ztq4EdzoBo;W1Oln&p6>-O1dLj}D`37HzjG}Z$mEbjN+93#e7AKz>btt5 z`a@S>sX2Dku&cBe-v2nw;MAK6tTgW^e@N<)@_d1E?YMc}Mmx}+KRB#+B^Cv$bJ^3V zdAseuoj9*Ylc9wIG7|R%YIkE>ZV-HALOi*JBFf=3%l{XTHDK{9R`5V#RbXw7H7Xr5 z<**h?lAH!g2Nu@xNMb{vcs)+%RF6M|vgA;W)SGa;pdBdZeMc*Y>X}LpC{*zl5y(ui zt2x`ejQsItW#v3fwHNCy?MDH;Sj^&88K!$;J%n%P4H|48wqhEYDmFpk3fC zgL}x+6DEHm&ZOPBLZLU~LSCWRGrz&;8N2NnN=JKNP!WWsTl=5!@RDg2zE+i=L2_V~ z1R!CWloc$}zl2S$$u>$+=|)UX-xhIcY~V4TL@aq?b~wu>5jE7w*C3*d#4pkt61x(6 QlG`LC)=g#{Fq(k<8z_3(WB>pF literal 0 HcmV?d00001 diff --git a/target/test-classes/org/stefan/snrpc/server/SnRpcImpl.class b/target/test-classes/org/stefan/snrpc/server/SnRpcImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d0c4b87cfb40fedb13038d735b6be4c431537e84 GIT binary patch literal 729 zcmaJ<+iuf95IvJ7aT-iZLoeLx7Fwkg;s+jscmRQf6hI;l{l54K;1%{f)CfD7iNnImsnB7eO&*1XG^f&pL;W?6 zKBjr%p-#ASB2Gn^2pxxC#wRke9-4&xn}fBLW-1~{Xueij**Aox?!kyqf0s>U8%wz5 z!$XU(I#61Eo~2`HzKLqSHo;(BKbkN*01~Otj`ol8*=N}-olV^4 zyI%pYf>pM7k+8y^G~T)uhz&cWFCR