serverConfigs) {
85 | this.serverConfigs = serverConfigs;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/config/api/ServerConfig.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.config.api;
2 |
3 | import com.linkedkeeper.easyrpc.server.RpcServer;
4 |
5 | public class ServerConfig extends AbstractInterfaceConfig {
6 |
7 | /**
8 | * 绑定的地址。是某个网卡,还是全部地址
9 | */
10 | private final String host = "127.0.0.1";
11 |
12 | /**
13 | * 监听端口
14 | */
15 | protected int port;
16 |
17 | /**
18 | * 服务端对象
19 | */
20 | private volatile transient RpcServer server = null;
21 |
22 | public void start() throws Exception {
23 | if (server == null) {
24 | server = new RpcServer(host + ":" + port);
25 | }
26 | }
27 |
28 | /**
29 | * Gets server.
30 | *
31 | * @return the server
32 | */
33 | public RpcServer getServer() {
34 | return server;
35 | }
36 |
37 | public int getPort() {
38 | return port;
39 | }
40 |
41 | public void setPort(int port) {
42 | this.port = port;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/config/spring/ConsumerBean.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.config.spring;
2 |
3 | import com.linkedkeeper.easyrpc.client.RpcClient;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.beans.BeansException;
7 | import org.springframework.beans.factory.BeanNameAware;
8 | import org.springframework.beans.factory.DisposableBean;
9 | import org.springframework.beans.factory.InitializingBean;
10 | import org.springframework.context.ApplicationContext;
11 | import org.springframework.context.ApplicationContextAware;
12 |
13 | public class ConsumerBean extends ConsumerFactoryBean implements InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware {
14 |
15 | /**
16 | * slf4j logger for this class
17 | */
18 | private Logger logger = LoggerFactory.getLogger(ConsumerBean.class);
19 |
20 | protected transient ApplicationContext applicationContext = null;
21 | private transient String beanName = null;
22 |
23 | /**
24 | * @param name
25 | * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
26 | */
27 | @Override
28 | public void setBeanName(String name) {
29 | this.beanName = name;
30 | }
31 |
32 | /**
33 | * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
34 | *
35 | * 不支持Spring3.2以下版本, 无法通过addApplicationListener启动export
36 | */
37 | @Override
38 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
39 | this.applicationContext = applicationContext;
40 | }
41 |
42 | @Override
43 | public void afterPropertiesSet() throws Exception {
44 | }
45 |
46 | @Override
47 | public void destroy() throws Exception {
48 | logger.info("easy rpc destroy consumer with beanName {}", beanName);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/config/spring/ConsumerFactoryBean.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.config.spring;
2 |
3 | import com.linkedkeeper.easyrpc.config.api.ConsumerConfig;
4 | import org.springframework.beans.factory.FactoryBean;
5 |
6 | public class ConsumerFactoryBean extends ConsumerConfig implements FactoryBean {
7 |
8 | private transient T bean = null;
9 | private transient Class> objectType = null;
10 |
11 | @Override
12 | public T getObject() throws Exception {
13 | bean = refer();
14 | return bean;
15 | }
16 |
17 | @Override
18 | public Class> getObjectType() {
19 | try {
20 | objectType = getProxyClass();
21 | } catch (Exception e) {
22 | objectType = null;
23 | }
24 | return objectType;
25 | }
26 |
27 | @Override
28 | public boolean isSingleton() {
29 | return true;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/config/spring/ProviderBean.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.config.spring;
2 |
3 | import com.linkedkeeper.easyrpc.config.api.ProviderConfig;
4 | import com.linkedkeeper.easyrpc.config.api.ServerConfig;
5 | import com.linkedkeeper.easyrpc.server.RpcServer;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.BeansException;
9 | import org.springframework.beans.factory.BeanNameAware;
10 | import org.springframework.beans.factory.DisposableBean;
11 | import org.springframework.beans.factory.InitializingBean;
12 | import org.springframework.context.ApplicationContext;
13 | import org.springframework.context.ApplicationContextAware;
14 | import org.springframework.util.CollectionUtils;
15 |
16 | import java.util.ArrayList;
17 | import java.util.List;
18 | import java.util.Map;
19 |
20 | public class ProviderBean extends ProviderConfig implements InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware {
21 |
22 | /**
23 | * slf4j logger for this class
24 | */
25 | private Logger logger = LoggerFactory.getLogger(ProviderBean.class);
26 |
27 | protected transient ApplicationContext applicationContext = null;
28 | private transient String beanName = null;
29 |
30 | /**
31 | * @param name
32 | * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
33 | */
34 | @Override
35 | public void setBeanName(String name) {
36 | this.beanName = name;
37 | }
38 |
39 | /**
40 | * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
41 | *
42 | * 不支持Spring3.2以下版本, 无法通过addApplicationListener启动export
43 | */
44 | @Override
45 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
46 | this.applicationContext = applicationContext;
47 | }
48 |
49 | /**
50 | * Using implements InitializingBean
51 | */
52 | @Override
53 | public void afterPropertiesSet() throws Exception {
54 | propertiesInit();
55 | export();
56 | }
57 |
58 | /*
59 | * 组装相应的ServiceConfig
60 | */
61 | private void propertiesInit() {
62 | if (applicationContext != null) {
63 | if (getServerConfigs() == null) {
64 | Map protocolMaps = applicationContext.getBeansOfType(ServerConfig.class, false, false);
65 | if (!CollectionUtils.isEmpty(protocolMaps)) {
66 | List protocolLists = new ArrayList(protocolMaps.values());
67 | setServerConfigs(protocolLists);
68 | }
69 | }
70 | }
71 | }
72 |
73 | @Override
74 | public void destroy() throws Exception {
75 | logger.info("easy rpc destroy provider with beanName {}", beanName);
76 | // todo unexport
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/config/spring/ServerBean.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.config.spring;
2 |
3 | import com.linkedkeeper.easyrpc.config.api.ServerConfig;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.beans.factory.BeanNameAware;
7 | import org.springframework.beans.factory.DisposableBean;
8 | import org.springframework.beans.factory.InitializingBean;
9 |
10 | public class ServerBean extends ServerConfig implements InitializingBean, DisposableBean, BeanNameAware {
11 |
12 | /**
13 | * slf4j logger for this class
14 | */
15 | private Logger logger = LoggerFactory.getLogger(ServerBean.class);
16 |
17 | private transient String beanName = null;
18 |
19 | /**
20 | * @param name
21 | * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
22 | */
23 | @Override
24 | public void setBeanName(String name) {
25 | this.beanName = name;
26 | }
27 |
28 | @Override
29 | public void afterPropertiesSet() throws Exception {
30 | }
31 |
32 | @Override
33 | public void destroy() throws Exception {
34 | logger.info("Stop server with beanName {}", beanName);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/config/spring/schema/EasyRpcBeanDefinitionParser.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.config.spring.schema;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.springframework.beans.factory.config.BeanDefinition;
5 | import org.springframework.beans.factory.config.BeanReference;
6 | import org.springframework.beans.factory.config.RuntimeBeanReference;
7 | import org.springframework.beans.factory.support.ManagedList;
8 | import org.springframework.beans.factory.support.RootBeanDefinition;
9 | import org.springframework.beans.factory.xml.BeanDefinitionParser;
10 | import org.springframework.beans.factory.xml.ParserContext;
11 | import org.w3c.dom.Element;
12 |
13 | import java.lang.reflect.Method;
14 | import java.lang.reflect.Modifier;
15 |
16 | public class EasyRpcBeanDefinitionParser implements BeanDefinitionParser {
17 |
18 | private final Class> beanClass;
19 | private final boolean required;
20 |
21 | public EasyRpcBeanDefinitionParser(Class> beanClass, boolean required) {
22 | this.beanClass = beanClass;
23 | this.required = required;
24 | }
25 |
26 | /**
27 | * Method Name parse
28 | *
29 | * @param element
30 | * @param parserContext
31 | * @return Return Type BeanDefinition
32 | */
33 | @Override
34 | public BeanDefinition parse(Element element, ParserContext parserContext) {
35 | return parse(element, parserContext, this.beanClass, this.required);
36 | }
37 |
38 |
39 | private BeanDefinition parse(Element element, ParserContext parserContext, Class> beanClass, boolean required) {
40 | RootBeanDefinition beanDefinition = new RootBeanDefinition();
41 | beanDefinition.setBeanClass(beanClass);
42 | beanDefinition.setLazyInit(false);
43 |
44 | String id = element.getAttribute("id");
45 | if (StringUtils.isBlank(id) && required) {
46 | throw new IllegalStateException("This bean do not set spring bean id " + id);
47 | }
48 |
49 | // id肯定是必须的所以此处去掉对id是否为空的判断
50 | if (required) {
51 | if (parserContext.getRegistry().containsBeanDefinition(id)) {
52 | throw new IllegalStateException("Duplicate spring bean id " + id);
53 | }
54 | parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
55 | }
56 |
57 | // set各个属性
58 | for (Method setter : beanClass.getMethods()) {
59 | if (isProperty(setter, beanClass)) {
60 | String name = setter.getName();
61 | String property = name.substring(3, 4).toLowerCase() + name.substring(4);
62 | String value = element.getAttribute(property).trim();
63 | Object reference = value;
64 | //根据property名称来进行区别处理
65 | switch (property) {
66 | case "protocol":
67 | case "interface":
68 | if (StringUtils.isNotBlank(value)) {
69 | beanDefinition.getPropertyValues().addPropertyValue(property, reference);
70 | }
71 | break;
72 | case "ref":
73 | if (StringUtils.isNotBlank(value)) {
74 | BeanDefinition refBean = parserContext.getRegistry().getBeanDefinition(value);
75 | if (!refBean.isSingleton()) {
76 | throw new IllegalStateException("The exported service ref " + value + " must be singleton! Please set the " + value + " bean scope to singleton, eg: ");
77 | }
78 | reference = new RuntimeBeanReference(value);
79 | } else {
80 | // 保持ref的null值
81 | reference = null;
82 | }
83 | beanDefinition.getPropertyValues().addPropertyValue(property, reference);
84 | break;
85 | case "server":
86 | parseMultiRef(property, value, beanDefinition);
87 | break;
88 | default:
89 | // 默认非空字符串只是绑定值到属性
90 | if (StringUtils.isNotBlank(value)) {
91 | beanDefinition.getPropertyValues().addPropertyValue(property, reference);
92 | }
93 | break;
94 | }
95 | }
96 | }
97 | return beanDefinition;
98 | }
99 |
100 | private void parseMultiRef(String property, String value, RootBeanDefinition beanDefinition) {
101 | String[] values = value.split("\\s*[,]+\\s*");
102 | ManagedList list = null;
103 | for (String v : values) {
104 | if (StringUtils.isNotBlank(v)) {
105 | if (list == null) {
106 | list = new ManagedList();
107 | }
108 | list.add(new RuntimeBeanReference(v));
109 | }
110 | }
111 | beanDefinition.getPropertyValues().addPropertyValue(property, list);
112 | }
113 |
114 | /**
115 | * 判断是否有相应get\set方法的property
116 | */
117 | protected boolean isProperty(Method method, Class beanClass) {
118 | String methodName = method.getName();
119 | boolean flag = methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 1;
120 | Method getter = null;
121 | if (flag) {
122 | Class> type = method.getParameterTypes()[0];
123 | try {
124 | getter = beanClass.getMethod("get" + methodName.substring(3), new Class>[0]);
125 | } catch (NoSuchMethodException e) {
126 | try {
127 | getter = beanClass.getMethod("is" + methodName.substring(3), new Class>[0]);
128 | } catch (NoSuchMethodException e2) {
129 | }
130 | }
131 | flag = getter != null && Modifier.isPublic(getter.getModifiers()) && type.equals(getter.getReturnType());
132 | }
133 | return flag;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/config/spring/schema/EasyRpcNamespaceHandler.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.config.spring.schema;
2 |
3 | import com.linkedkeeper.easyrpc.config.spring.ConsumerBean;
4 | import com.linkedkeeper.easyrpc.config.spring.ProviderBean;
5 | import com.linkedkeeper.easyrpc.config.spring.ServerBean;
6 | import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
7 |
8 | /**
9 | * Title: 继承NamespaceHandlerSupport,将xml的标签绑定到解析器
10 | *
11 | * Description: 在META-INF下增加spring.handlers和spring.schemas
12 | */
13 | public class EasyRpcNamespaceHandler extends NamespaceHandlerSupport {
14 | @Override
15 | public void init() {
16 | registerBeanDefinitionParser("provider", new EasyRpcBeanDefinitionParser(ProviderBean.class, true));
17 | registerBeanDefinitionParser("consumer", new EasyRpcBeanDefinitionParser(ConsumerBean.class, true));
18 | registerBeanDefinitionParser("server", new EasyRpcBeanDefinitionParser(ServerBean.class, true));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/server/RpcHandler.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.server;
2 |
3 | import com.linkedkeeper.easyrpc.codec.RpcRequest;
4 | import com.linkedkeeper.easyrpc.codec.RpcResponse;
5 | import io.netty.channel.ChannelFuture;
6 | import io.netty.channel.ChannelFutureListener;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import io.netty.channel.SimpleChannelInboundHandler;
9 | import net.sf.cglib.reflect.FastClass;
10 | import net.sf.cglib.reflect.FastMethod;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | import java.lang.reflect.Method;
15 | import java.util.Map;
16 | import java.util.concurrent.ArrayBlockingQueue;
17 | import java.util.concurrent.ThreadPoolExecutor;
18 | import java.util.concurrent.TimeUnit;
19 |
20 | public class RpcHandler extends SimpleChannelInboundHandler {
21 |
22 | private static final Logger LOGGER = LoggerFactory.getLogger(RpcHandler.class);
23 |
24 | private ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 16, 600L, TimeUnit.SECONDS, new ArrayBlockingQueue(65536));
25 |
26 | private final Map handlerMap;
27 |
28 | public RpcHandler(Map handlerMap) {
29 | this.handlerMap = handlerMap;
30 | }
31 |
32 | protected void channelRead0(final ChannelHandlerContext ctx, final RpcRequest request) throws Exception {
33 | executor.submit(new Runnable() {
34 | public void run() {
35 | LOGGER.debug("Receive request " + request.getRequestId());
36 | RpcResponse response = new RpcResponse();
37 | response.setRequestId(request.getRequestId());
38 | try {
39 | Object result = handle(request);
40 | response.setResult(result);
41 | } catch (Throwable t) {
42 | response.setError(t.toString());
43 | LOGGER.error("RPC Server handle request error", t);
44 | }
45 | ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
46 | public void operationComplete(ChannelFuture future) throws Exception {
47 | LOGGER.debug("Send response for request " + request.getRequestId());
48 | }
49 | });
50 | }
51 | });
52 | }
53 |
54 | private Object handle(RpcRequest request) throws Throwable {
55 | String className = request.getClassName();
56 | Object serviceBean = handlerMap.get(className);
57 |
58 | Class> serviceClass = serviceBean.getClass();
59 | String methodName = request.getMethodName();
60 | Class>[] parameterTypes = request.getParameterTypes();
61 | Object[] parameters = request.getParameters();
62 |
63 | // JDK reflect
64 | Method method = serviceClass.getMethod(methodName, parameterTypes);
65 | method.setAccessible(true);
66 | return method.invoke(serviceBean, parameters);
67 |
68 | // Cglib reflect
69 | /**FastClass serviceFastClass = FastClass.create(serviceClass);
70 | FastMethod serviceFastMethod = serviceFastClass.getMethod(methodName, parameterTypes);
71 | return serviceFastMethod.invoke(serviceBean, parameters);**/
72 | }
73 |
74 | public void exceptiionCaught(ChannelHandlerContext ctx, Throwable cause) {
75 | LOGGER.error("server caught exception", cause);
76 | ctx.close();
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/linkedkeeper/easyrpc/server/RpcServer.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.server;
2 |
3 | import com.linkedkeeper.easyrpc.codec.RpcDecoder;
4 | import com.linkedkeeper.easyrpc.codec.RpcEncoder;
5 | import com.linkedkeeper.easyrpc.codec.RpcRequest;
6 | import com.linkedkeeper.easyrpc.codec.RpcResponse;
7 | import com.linkedkeeper.easyrpc.config.api.ProviderConfig;
8 | import io.netty.bootstrap.ServerBootstrap;
9 | import io.netty.channel.*;
10 | import io.netty.channel.nio.NioEventLoopGroup;
11 | import io.netty.channel.socket.SocketChannel;
12 | import io.netty.channel.socket.nio.NioServerSocketChannel;
13 | import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 | import org.springframework.beans.factory.DisposableBean;
17 | import org.springframework.beans.factory.InitializingBean;
18 |
19 | import java.util.HashMap;
20 | import java.util.Map;
21 | import java.util.concurrent.TimeUnit;
22 |
23 | public class RpcServer {
24 |
25 | private static final Logger LOGGER = LoggerFactory.getLogger(RpcServer.class);
26 |
27 | private String serverAddress;
28 | public volatile Map handleMap = new HashMap();
29 |
30 | EventLoopGroup bossGroup = new NioEventLoopGroup();
31 | EventLoopGroup workerGroup = new NioEventLoopGroup();
32 |
33 | public RpcServer(String serverAddress) throws Exception {
34 | this.serverAddress = serverAddress;
35 | this.startServer();
36 | }
37 |
38 | public void registerProcessor(ProviderConfig providerConfig) {
39 | handleMap.put(providerConfig.getInterface(), providerConfig.getRef());
40 | }
41 |
42 | private void startServer() throws Exception {
43 | ServerBootstrap bootstrap = new ServerBootstrap();
44 | bootstrap.group(bossGroup, workerGroup)
45 | .channel(NioServerSocketChannel.class)
46 | .childHandler(new ChannelInitializer() {
47 | public void initChannel(SocketChannel ch) throws Exception {
48 | ch.pipeline()
49 | .addLast(new LengthFieldBasedFrameDecoder(65536, 0, 4, 0, 0))
50 | .addLast(new RpcDecoder(RpcRequest.class))
51 | .addLast(new RpcEncoder(RpcResponse.class))
52 | .addLast(new RpcHandler(handleMap));
53 | }
54 | })
55 | .option(ChannelOption.SO_BACKLOG, 128)
56 | .childOption(ChannelOption.SO_KEEPALIVE, true);
57 |
58 | String[] array = serverAddress.split(":");
59 | String host = array[0];
60 | int port = Integer.parseInt(array[1]);
61 |
62 | ChannelFuture future = bootstrap.bind(host, port).sync();
63 | ChannelFuture channelFuture = future.addListener(new ChannelFutureListener() {
64 | public void operationComplete(ChannelFuture future) throws Exception {
65 | if (future.isSuccess()) {
66 | LOGGER.info("Server have success bind to " + serverAddress);
67 | } else {
68 | LOGGER.error("Server fail bind to " + serverAddress);
69 | throw new Exception("Server start fail !", future.cause());
70 | }
71 | }
72 | });
73 |
74 | try {
75 | channelFuture.await(5000, TimeUnit.MILLISECONDS);
76 | if (channelFuture.isSuccess()) {
77 | LOGGER.info("start easy rpc server success.");
78 | }
79 |
80 | } catch (InterruptedException e) {
81 | LOGGER.error("start easy rpc occur InterruptedException!", e);
82 | }
83 | }
84 |
85 | public void destroy() throws Exception {
86 | workerGroup.shutdownGracefully();
87 | bossGroup.shutdownGracefully();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/easyrpc.xsd:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/spring.handlers:
--------------------------------------------------------------------------------
1 | http\://www.linkedkeeper.com/schema/easyrpc=com.linkedkeeper.easyrpc.config.spring.schema.EasyRpcNamespaceHandler
--------------------------------------------------------------------------------
/src/main/resources/META-INF/spring.schemas:
--------------------------------------------------------------------------------
1 | http\://www.linkedkeeper.com/schema/easyrpc/easyrpc.xsd=META-INF/easyrpc.xsd
--------------------------------------------------------------------------------
/src/test/java/com/linkedkeeper/easyrpc/test/client/HelloService.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.test.client;
2 |
3 | public interface HelloService {
4 |
5 | String hello(String name);
6 |
7 | String hello(Person person);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/test/java/com/linkedkeeper/easyrpc/test/client/HelloServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.test.client;
2 |
3 | import com.linkedkeeper.easyrpc.client.RpcClient;
4 | import com.linkedkeeper.easyrpc.client.RpcFuture;
5 | import com.linkedkeeper.easyrpc.client.proxy.IAsyncObjectProxy;
6 | import org.junit.After;
7 | import org.junit.Assert;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.test.context.ContextConfiguration;
12 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
13 |
14 | import java.util.concurrent.ExecutionException;
15 |
16 | @RunWith(SpringJUnit4ClassRunner.class)
17 | @ContextConfiguration(locations = "classpath:spring-client.xml")
18 | public class HelloServiceTest {
19 |
20 | @Autowired
21 | private RpcClient rpcClient = null;
22 |
23 | @Test
24 | public void helloTest1() {
25 | HelloService helloService = rpcClient.create(HelloService.class);
26 | String result = helloService.hello("World");
27 | System.out.println(result);
28 | Assert.assertEquals("Hello! World", result);
29 | }
30 |
31 | @Test
32 | public void helloTest2() {
33 | HelloService helloService = rpcClient.create(HelloService.class);
34 | Person person = new Person("Yong", "Huang");
35 | String result = helloService.hello(person);
36 | System.out.println(result.toString());
37 | Assert.assertEquals("Hello! Yong Huang", result);
38 | }
39 |
40 | @Test
41 | public void helloFutureTest1() throws ExecutionException, InterruptedException {
42 | IAsyncObjectProxy helloService = rpcClient.createAsync(HelloService.class);
43 | RpcFuture result = helloService.call("hello", "World");
44 | Assert.assertEquals("Hello! World", result.get());
45 | }
46 |
47 | @Test
48 | public void helloFutureTest2() throws ExecutionException, InterruptedException {
49 | IAsyncObjectProxy helloService = rpcClient.createAsync(HelloService.class);
50 | Person person = new Person("Yong", "Huang");
51 | RpcFuture result = helloService.call("hello", person);
52 | Assert.assertEquals("Hello! Yong Huang", result.get());
53 | }
54 |
55 | @After
56 | public void setTear() {
57 | if (rpcClient != null) {
58 | rpcClient.stop();
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/test/java/com/linkedkeeper/easyrpc/test/client/Person.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.test.client;
2 |
3 | public class Person {
4 |
5 | private String firstName;
6 | private String lastName;
7 |
8 | public Person() {
9 | }
10 |
11 | public Person(String firstName, String lastName) {
12 | this.firstName = firstName;
13 | this.lastName = lastName;
14 | }
15 |
16 | public String getFirstName() {
17 | return firstName;
18 | }
19 |
20 | public void setFirstName(String firstName) {
21 | this.firstName = firstName;
22 | }
23 |
24 | public String getLastName() {
25 | return lastName;
26 | }
27 |
28 | public void setLastName(String lastName) {
29 | this.lastName = lastName;
30 | }
31 |
32 | @Override
33 | public String toString() {
34 | return firstName + " " + lastName;
35 | }
36 |
37 | @Override
38 | public int hashCode() {
39 | return this.firstName.hashCode() ^ this.lastName.hashCode();
40 | }
41 |
42 | @Override
43 | public boolean equals(Object obj) {
44 | if (!(obj instanceof Person)) return false;
45 | Person p = (Person) obj;
46 | return this.firstName.equals(p.firstName) && this.lastName.equals(p.lastName);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/com/linkedkeeper/easyrpc/test/server/HelloServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.test.server;
2 |
3 | import com.linkedkeeper.easyrpc.test.client.HelloService;
4 | import com.linkedkeeper.easyrpc.test.client.Person;
5 |
6 | public class HelloServiceImpl implements HelloService {
7 |
8 | public String hello(String name) {
9 | return "Hello! " + name;
10 | }
11 |
12 | public String hello(Person person) {
13 | return "Hello! " + person.getFirstName() + " " + person.getLastName();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/test/java/com/linkedkeeper/easyrpc/test/server/RpcBootstrap.java:
--------------------------------------------------------------------------------
1 | package com.linkedkeeper.easyrpc.test.server;
2 |
3 | import org.springframework.context.support.ClassPathXmlApplicationContext;
4 |
5 | public class RpcBootstrap {
6 |
7 | public static void main(String[] args) {
8 | new ClassPathXmlApplicationContext("spring-server.xml");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=Info,console,file
2 |
3 | log4j.appender.console=org.apache.log4j.ConsoleAppender
4 | log4j.appender.console.target=System.out
5 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
6 | log4j.appender.console.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
7 |
8 | log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
9 | log4j.appender.file.File = /Users/sauronzhang/Desktop/logs/easyrpc.log
10 | log4j.appender.file.Append = true
11 | log4j.appender.file.Threshold = Error
12 | log4j.appender.file.layout = org.apache.log4j.PatternLayout
13 | log4j.appender.file.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n
--------------------------------------------------------------------------------
/src/test/resources/spring-client.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/src/test/resources/spring-server.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------