Repository: incubator-rocketmq
Updated Branches:
  refs/heads/rocketmq5 [created] 0b88e66fa


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyCommon.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyCommon.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyCommon.java
new file mode 100644
index 0000000..c5d9a3c
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyCommon.java
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.impl.service;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.ByteBuffer;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.apache.rocketmq.remoting.api.AsyncHandler;
+import org.apache.rocketmq.remoting.api.RemotingService;
+import org.apache.rocketmq.remoting.api.command.RemotingCommand;
+import org.apache.rocketmq.remoting.api.serializable.Serializer;
+import org.apache.rocketmq.remoting.api.serializable.SerializerFactory;
+import org.apache.rocketmq.remoting.external.ThreadUtils;
+import 
org.apache.rocketmq.remoting.impl.protocol.serializer.SerializerFactoryImpl;
+import org.apache.rocketmq.rpc.annotation.MethodType;
+import org.apache.rocketmq.rpc.annotation.RemoteMethod;
+import org.apache.rocketmq.rpc.annotation.RemoteService;
+import org.apache.rocketmq.rpc.annotation.VisibleForInternal;
+import org.apache.rocketmq.rpc.api.Promise;
+import org.apache.rocketmq.rpc.api.PromiseListener;
+import org.apache.rocketmq.rpc.impl.command.ResponseCode;
+import org.apache.rocketmq.rpc.impl.command.RpcRequestCode;
+import org.apache.rocketmq.rpc.impl.config.RpcCommonConfig;
+import org.apache.rocketmq.rpc.impl.context.RpcCallerContext;
+import org.apache.rocketmq.rpc.impl.exception.ServiceExceptionHandlerManager;
+import org.apache.rocketmq.rpc.impl.exception.ServiceExceptionManager;
+import org.apache.rocketmq.rpc.impl.metrics.ServiceStats;
+import org.apache.rocketmq.rpc.impl.promise.DefaultPromise;
+import org.apache.rocketmq.rpc.internal.ExceptionMessageUtil;
+import org.apache.rocketmq.rpc.internal.RpcErrorMapper;
+import org.apache.rocketmq.rpc.internal.ServiceUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static 
org.apache.rocketmq.remoting.internal.ExceptionUtils.getStackTrace;
+
+public abstract class RpcProxyCommon {
+    protected final static SerializerFactory SERIALIZER_FACTORY = new 
SerializerFactoryImpl();
+    protected static final Logger log = 
LoggerFactory.getLogger(RpcProxyCommon.class);
+    protected final ThreadLocal<RpcCallerContext> threadLocalCallerContext = 
new ThreadLocal<>();
+    protected RpcCommonConfig rpcCommonConfig;
+    protected ExecutorService callServiceThreadPool;
+    protected ExecutorService promiseExecutorService;
+    protected ServiceStats serviceStats;
+
+    public RpcProxyCommon(RpcCommonConfig rpcCommonConfig) {
+        this.rpcCommonConfig = rpcCommonConfig;
+        this.serviceStats = new ServiceStats();
+        this.promiseExecutorService = 
ThreadUtils.newThreadPoolExecutor(rpcCommonConfig.getClientAsyncCallbackExecutorThreads(),
+            rpcCommonConfig.getClientAsyncCallbackExecutorThreads(), 
rpcCommonConfig.getServiceThreadKeepAliveTime(),
+            TimeUnit.MILLISECONDS, new 
ArrayBlockingQueue<Runnable>(rpcCommonConfig.getServiceThreadBlockQueueSize()), 
"promiseExecutorService", true);
+        this.callServiceThreadPool = 
ThreadUtils.newThreadPoolExecutor(rpcCommonConfig.getClientAsyncCallbackExecutorThreads(),
+            rpcCommonConfig.getClientAsyncCallbackExecutorThreads(), 
rpcCommonConfig.getServiceThreadKeepAliveTime(),
+            TimeUnit.MILLISECONDS, new 
ArrayBlockingQueue<Runnable>(rpcCommonConfig.getServiceThreadBlockQueueSize()), 
"callServiceThread", true);
+    }
+
+    private RemotingCommand createRemoteRequest(RemoteService serviceExport, 
Method method, Object[] args,
+        RemoteMethod asynchronous) {
+        RemotingCommand request;
+        VisibleForInternal visible = 
method.getAnnotation(VisibleForInternal.class);
+        if (visible != null) {
+            request = remotingService().commandFactory().createRequest();
+            request.opCode(asynchronous.name());
+            if (args != null && args.length != 0) {
+                request.parameter(args[0]);
+            }
+        } else {
+            String requestCode = ServiceUtil.toRequestCode(serviceExport, 
method);
+            request = createRemoteRequest(requestCode, asynchronous.version(), 
args);
+        }
+        return request;
+    }
+
+    public RemotingCommand createRemoteRequest(String requestCode, String 
version, Object[] args) {
+        RemotingCommand request = 
remotingService().commandFactory().createRequest();
+        request.opCode(RpcRequestCode.CALL_SERVICE);
+        RpcServiceCallBody serviceCallBody = new RpcServiceCallBody();
+        serviceCallBody.setServiceId(requestCode);
+
+        if (args != null) {
+            Serializer serializer = ServiceUtil.selectSerializer(args, 
SERIALIZER_FACTORY.type(rpcCommonConfig.getSerializerName()));
+            assert serializer != null;
+            request.serializerType(serializer.type());
+            for (Object arg : args) {
+                ByteBuffer byteBuffer = serializer.encode(arg);
+                byte[] array = new byte[byteBuffer.remaining()];
+                byteBuffer.get(array);
+                serviceCallBody.addParameter(array);
+            }
+        }
+        serviceCallBody.setServiceVersion(version);
+        request.parameter(serviceCallBody);
+        return request;
+    }
+
+    @SuppressWarnings("unchecked")
+    Object invoke0(Object proxy, RpcJdkProxy rpcJdkProxy, Class<?> service, 
final Method method,
+        Object[] args) throws Throwable {
+        RemoteMethod asynchronous = getRemoteMethod(method);
+        final String requestCode = createRequestCode(method, service);
+        RemoteService serviceExport = getRemoteService(service);
+        RemotingCommand request = createRemoteRequest(serviceExport, method, 
args, asynchronous);
+        return invokeRemoteMethod(rpcJdkProxy, requestCode, request, 
method.getGenericReturnType(), asynchronous.type());
+    }
+
+    public Object invokeRemoteMethod(final RpcJdkProxy rpcJdkProxy, final 
String requestCode,
+        RemotingCommand request, final Type returnType, MethodType type) {
+        try {
+            final long startTime = System.currentTimeMillis();
+            InvokeRunnable invokeRunnable = new InvokeRunnable(rpcJdkProxy, 
requestCode, request, type);
+            final Future future = callServiceThreadPool.submit(invokeRunnable);
+            /*
+            final Promise result = callService(method, args);
+            */
+            final DefaultPromise resPromise = new DefaultPromise();
+            Object result = 
future.get(rpcCommonConfig.getClientInvokeServiceTimeout(), 
TimeUnit.MILLISECONDS);
+            if (result == null || !(result instanceof Promise)) {
+                throw 
ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
+                    new Exception("illegal response type is return"));
+            } else if (result instanceof Exception) {
+                throw 
ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
+                    new Exception((Throwable) result));
+            }
+
+            final DefaultPromise promise = (DefaultPromise) result;
+            switch (type) {
+                case SYNC:
+                    final Object response = 
promise.get(rpcCommonConfig.getClientInvokeServiceTimeout());
+                    if (response == null) {
+                        throw new Exception("get result is null");
+                    }
+                    if (response instanceof Exception)
+                        throw (Exception) response;
+                    return processResponse(returnType, (RemotingCommand) 
response,
+                        requestCode, startTime);
+                case ASYNC:
+                    promiseExecutorService.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            promise.addListener(new PromiseListener() {
+                                @Override
+                                public void operationCompleted(Promise 
promise) {
+                                    Object response = promise.get();
+                                    if (response == null) {
+                                        resPromise.setFailure(new 
Exception("get result is null"));
+                                        return;
+                                    }
+                                    if (response instanceof Exception) {
+                                        resPromise.setFailure((Exception) 
response);
+                                        return;
+                                    }
+                                    Type restyle = ((ParameterizedType) 
returnType).getActualTypeArguments()[0];
+                                    try {
+                                        
resPromise.set(processResponse(restyle, (RemotingCommand) response, 
requestCode, startTime));
+                                    } catch (Exception e) {
+                                        
resPromise.setFailure(ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
 e));
+                                    }
+                                }
+
+                                @Override
+                                public void operationFailed(Promise promise) {
+                                    
resPromise.setFailure(ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
 promise.getThrowable()));
+                                }
+                            });
+                        }
+                    });
+                    return resPromise;
+            }
+            throw 
ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
 new Exception("illegal response type is return"));
+        } catch (ExecutionException e) {
+            throw 
ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
 e.getCause());
+        } catch (Exception e) {
+            throw 
ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
 e);
+        }
+    }
+
+    private Object processResponse(Type returnType, RemotingCommand 
remotingCommand,
+        String requestCode, long startTime) throws Exception {
+        RpcCallerContext rpcCallerContext = 
this.threadLocalCallerContext.get();
+        if (rpcCallerContext != null) {
+            rpcCallerContext.setRemotingResponse(remotingCommand);
+        }
+
+        String code = remotingCommand.opCode();
+        if (code.equals(ResponseCode.SUCCESS)) {
+            serviceStats.addCallerOKQPSValue(requestCode, 1, 1);
+            serviceStats.addCallerRTValue(requestCode, (int) 
(System.currentTimeMillis() - startTime), 1);
+            try {
+                if (!returnType.equals(Void.class)) {
+                    Serializer serialization = 
remotingService().serializerFactory().get(remotingCommand.serializerType());
+                    if (remotingCommand.parameterBytes() == null)
+                        return null;
+                    return 
serialization.decode(remotingCommand.parameterBytes(), returnType);
+                } else {
+                    return Void.class.newInstance();
+                }
+            } catch (Exception e) {
+                throw 
ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
 e);
+            }
+        } else {
+            log.error("process response is failed, errorCode:{}, remark:{}", 
code, remotingCommand.remark());
+            serviceStats.addCallerFailedQPSValue(requestCode, 1, 1);
+            serviceStats.addCallerRTValue(requestCode, (int) 
(System.currentTimeMillis() - startTime), 1);
+            ServiceExceptionHandlerManager.exceptionHandler(code, 
remotingCommand, remotingService().serializerFactory());
+            return null;
+        }
+    }
+
+    private String createRequestCode(Method method, Class<?> service) {
+        return ServiceUtil.toRequestCode(getRemoteService(service), method);
+    }
+
+    private RemoteService getRemoteService(Class<?> service) {
+        RemoteService serviceExport = 
service.getAnnotation(RemoteService.class);
+        if (serviceExport == null) {
+            throw new IllegalArgumentException("ServiceExport:" + 
service.getName() + " do not remark annotation");
+        }
+        return serviceExport;
+    }
+
+    private RemoteMethod getRemoteMethod(Method method) {
+        RemoteMethod asynchronous = method.getAnnotation(RemoteMethod.class);
+        if (asynchronous == null) {
+            throw new IllegalArgumentException("ServiceMethod:" + 
method.getName() + " do not remark annotation");
+        }
+        return asynchronous;
+    }
+
+    private Promise invokeAsyncWrapper(final RpcJdkProxy rpcJdkProxy, 
RemotingCommand request,
+        final String requestCode) {
+        final RpcCallerContext rpcCallerContext = 
this.threadLocalCallerContext.get();
+        final DefaultPromise promise = new DefaultPromise();
+        final long startTime = System.currentTimeMillis();
+        rpcJdkProxy.invokeAsync(request, new AsyncHandler() {
+            @Override
+            public void onFailure(RemotingCommand request) {
+                serviceStats.addCallerFailedQPSValue(requestCode, 1, 1);
+                serviceStats.addCallerRTValue(requestCode, (int) 
(System.currentTimeMillis() - startTime), 1);
+                promise.setFailure(new 
Exception(ExceptionMessageUtil.buildExceptionMessage("request:" + 
request.toString() + " onFailure")));
+            }
+
+            @Override
+            public void onTimeout(long costTimeMillis, long timeoutMillis) {
+                serviceStats.addCallerFailedQPSValue(requestCode, 1, 1);
+                serviceStats.addCallerRTValue(requestCode, (int) 
(System.currentTimeMillis() - startTime), 1);
+                promise.setFailure(new 
Exception(ExceptionMessageUtil.buildExceptionMessage("service timeout")));
+            }
+
+            @Override
+            public void onSuccess(RemotingCommand response) {
+                if (null != rpcCallerContext) {
+                    rpcCallerContext.setRemotingResponse(response);
+                }
+                try {
+                    promise.set(response);
+                } catch (Throwable e) {
+                    promise.setFailure(new 
Exception(ExceptionMessageUtil.buildExceptionMessage(getStackTrace(e))));
+                }
+            }
+
+        });
+        return promise;
+    }
+
+    public abstract RemotingService remotingService();
+
+    public RpcCommonConfig getRpcCommonConfig() {
+        return rpcCommonConfig;
+    }
+
+    public void setRpcCommonConfig(final RpcCommonConfig rpcCommonConfig) {
+        this.rpcCommonConfig = rpcCommonConfig;
+    }
+
+    private class InvokeRunnable implements Callable {
+        private RpcJdkProxy rpcJdkProxy;
+        private String requestCode;
+        private RemotingCommand request;
+        private MethodType type;
+
+        InvokeRunnable(RpcJdkProxy rpcJdkProxy, String requestCode, 
RemotingCommand request,
+            MethodType type) {
+            this.rpcJdkProxy = rpcJdkProxy;
+            this.requestCode = requestCode;
+            this.request = request;
+            this.type = type;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Object call() {
+            Promise promise = new DefaultPromise();
+
+            try {
+                if (type == MethodType.ONEWAY) {
+                    rpcJdkProxy.invokeOneWay(request);
+                } else {
+                    return RpcProxyCommon.this.invokeAsyncWrapper(rpcJdkProxy, 
request, requestCode);
+                }
+            } catch (Exception e) {
+                
promise.set(ServiceExceptionManager.TranslateException(RpcErrorMapper.RpcErrorLatitude.LOCAL.getCode(),
 e));
+            }
+            return promise;
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyFactory.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyFactory.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyFactory.java
new file mode 100644
index 0000000..17abcd8
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcProxyFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.impl.service;
+
+import org.apache.rocketmq.remoting.api.RemotingClient;
+import org.apache.rocketmq.remoting.api.RemotingServer;
+import org.apache.rocketmq.remoting.api.channel.RemotingChannel;
+import org.apache.rocketmq.rpc.impl.config.RpcCommonConfig;
+
+public class RpcProxyFactory {
+    public static RpcJdkProxy createServiceProxy(Class<?> service,
+        RpcProxyCommon rpcProxyCommon,
+        RemotingClient remotingClient,
+        RpcCommonConfig rpcCommonConfig,
+        String remotingAddress) {
+        return new RpcJdkProxyClient(service, rpcProxyCommon, remotingClient, 
rpcCommonConfig, remotingAddress);
+    }
+
+    public static RpcJdkProxy createServiceProxy(Class<?> service,
+        RpcProxyCommon rpcProxyCommon,
+        RemotingServer remotingServer,
+        RpcCommonConfig rpcCommonConfig,
+        RemotingChannel remotingChannel) {
+        return new RpcJdkProxyServer(service, rpcProxyCommon, remotingServer, 
rpcCommonConfig, remotingChannel);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcServiceCallBody.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcServiceCallBody.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcServiceCallBody.java
new file mode 100644
index 0000000..ce78587
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/impl/service/RpcServiceCallBody.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.impl.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.msgpack.annotation.Message;
+
+@Message
+public class RpcServiceCallBody {
+    private String serviceId;
+    private String serviceVersion;
+    private String token;
+    private List<byte[]> parameters;
+
+    public RpcServiceCallBody() {
+        parameters = new ArrayList<>();
+    }
+
+    public String getServiceId() {
+        return serviceId;
+    }
+
+    public void setServiceId(final String serviceId) {
+        this.serviceId = serviceId;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(final String token) {
+        this.token = token;
+    }
+
+    public byte[] getParameter(int index) {
+        return parameters.get(index);
+    }
+
+    public List<byte[]> getParameters() {
+        return parameters;
+    }
+
+    public void setParameters(final List<byte[]> parameters) {
+        this.parameters = parameters;
+    }
+
+    public void addParameter(final byte[] parameter) {
+        parameters.add(parameter);
+    }
+
+    public String getServiceVersion() {
+        return serviceVersion;
+    }
+
+    public void setServiceVersion(final String serviceVersion) {
+        this.serviceVersion = serviceVersion;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ExceptionMessageUtil.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ExceptionMessageUtil.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ExceptionMessageUtil.java
new file mode 100644
index 0000000..de869f5
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ExceptionMessageUtil.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.internal;
+
+public class ExceptionMessageUtil {
+    public static String buildExceptionMessage(String msg) {
+        return msg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/HttpTinyClient.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/HttpTinyClient.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/HttpTinyClient.java
new file mode 100644
index 0000000..47c31c9
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/HttpTinyClient.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.internal;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Iterator;
+import java.util.List;
+
+public class HttpTinyClient {
+
+    static public HttpResult httpGet(String url, List<String> headers, 
List<String> paramValues,
+        String encoding, long readTimeoutMs) throws IOException {
+        String encodedContent = encodingParams(paramValues, encoding);
+        url += (null == encodedContent) ? "" : ("?" + encodedContent);
+
+        HttpURLConnection conn = null;
+        try {
+            conn = (HttpURLConnection) new URL(url).openConnection();
+            conn.setRequestMethod("GET");
+            conn.setConnectTimeout((int) readTimeoutMs);
+            conn.setReadTimeout((int) readTimeoutMs);
+            setHeaders(conn, headers, encoding);
+
+            conn.connect();
+            int respCode = conn.getResponseCode();
+            String resp = null;
+
+            if (HttpURLConnection.HTTP_OK == respCode) {
+                resp = IOTinyUtils.toString(conn.getInputStream(), encoding);
+            } else {
+                resp = IOTinyUtils.toString(conn.getErrorStream(), encoding);
+            }
+            return new HttpResult(respCode, resp);
+        } finally {
+            if (conn != null) {
+                conn.disconnect();
+            }
+        }
+    }
+
+    static private String encodingParams(List<String> paramValues, String 
encoding)
+        throws UnsupportedEncodingException {
+        StringBuilder sb = new StringBuilder();
+        if (null == paramValues) {
+            return null;
+        }
+
+        for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) 
{
+            sb.append(iter.next()).append("=");
+            sb.append(URLEncoder.encode(iter.next(), encoding));
+            if (iter.hasNext()) {
+                sb.append("&");
+            }
+        }
+        return sb.toString();
+    }
+
+    static private void setHeaders(HttpURLConnection conn, List<String> 
headers, String encoding) {
+        if (null != headers) {
+            for (Iterator<String> iter = headers.iterator(); iter.hasNext(); ) 
{
+                conn.addRequestProperty(iter.next(), iter.next());
+            }
+        }
+        conn.addRequestProperty("Client-Version", "V1.0.0");
+        
conn.addRequestProperty("Content-org.apache.rocketmq.annotation.MethodType", 
"application/x-www-form-urlencoded;charset=" + encoding);
+        String ts = String.valueOf(System.currentTimeMillis());
+        conn.addRequestProperty("Metaq-Client-RequestTS", ts);
+    }
+
+    static public HttpResult httpPost(String url, List<String> headers, 
List<String> paramValues,
+        String encoding, long readTimeoutMs) throws IOException {
+        String encodedContent = encodingParams(paramValues, encoding);
+
+        HttpURLConnection conn = null;
+        try {
+            conn = (HttpURLConnection) new URL(url).openConnection();
+            conn.setRequestMethod("POST");
+            conn.setConnectTimeout(3000);
+            conn.setReadTimeout((int) readTimeoutMs);
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+            setHeaders(conn, headers, encoding);
+
+            conn.getOutputStream().write(encodedContent.getBytes("UTF-8"));
+
+            int respCode = conn.getResponseCode();
+            String resp = null;
+
+            if (HttpURLConnection.HTTP_OK == respCode) {
+                resp = IOTinyUtils.toString(conn.getInputStream(), encoding);
+            } else {
+                resp = IOTinyUtils.toString(conn.getErrorStream(), encoding);
+            }
+            return new HttpResult(respCode, resp);
+        } finally {
+            if (null != conn) {
+                conn.disconnect();
+            }
+        }
+    }
+
+    static public class HttpResult {
+        final public int code;
+        final public String content;
+
+        public HttpResult(int code, String content) {
+            this.code = code;
+            this.content = content;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/IOTinyUtils.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/IOTinyUtils.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/IOTinyUtils.java
new file mode 100644
index 0000000..fddab17
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/IOTinyUtils.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.internal;
+
+import java.io.BufferedReader;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.List;
+
+public class IOTinyUtils {
+
+    static public String toString(InputStream input, String encoding) throws 
IOException {
+        return (null == encoding) ? toString(new InputStreamReader(input, 
"UTF-8")) : toString(new InputStreamReader(
+            input, encoding));
+    }
+
+    static public String toString(Reader reader) throws IOException {
+        CharArrayWriter sw = new CharArrayWriter();
+        copy(reader, sw);
+        return sw.toString();
+    }
+
+    static public long copy(Reader input, Writer output) throws IOException {
+        char[] buffer = new char[1 << 12];
+        long count = 0;
+        for (int n = 0; (n = input.read(buffer)) >= 0; ) {
+            output.write(buffer, 0, n);
+            count += n;
+        }
+        return count;
+    }
+
+    static public List<String> readLines(Reader input) throws IOException {
+        BufferedReader reader = toBufferedReader(input);
+        List<String> list = new ArrayList<String>();
+        String line = null;
+        for (; ; ) {
+            line = reader.readLine();
+            if (null != line) {
+                list.add(line);
+            } else {
+                break;
+            }
+        }
+        return list;
+    }
+
+    static private BufferedReader toBufferedReader(Reader reader) {
+        return reader instanceof BufferedReader ? (BufferedReader) reader : 
new BufferedReader(reader);
+    }
+
+    static public void copyFile(String source, String target) throws 
IOException {
+        File sf = new File(source);
+        if (!sf.exists()) {
+            throw new IllegalArgumentException("source file does not exist.");
+        }
+        File tf = new File(target);
+        tf.getParentFile().mkdirs();
+        if (!tf.exists() && !tf.createNewFile()) {
+            throw new RuntimeException("failed to create target file.");
+        }
+
+        FileChannel sc = null;
+        FileChannel tc = null;
+        try {
+            tc = new FileOutputStream(tf).getChannel();
+            sc = new FileInputStream(sf).getChannel();
+            sc.transferTo(0, sc.size(), tc);
+        } finally {
+            if (null != sc) {
+                sc.close();
+            }
+            if (null != tc) {
+                tc.close();
+            }
+        }
+    }
+
+    public static void delete(File fileOrDir) throws IOException {
+        if (fileOrDir == null) {
+            return;
+        }
+
+        if (fileOrDir.isDirectory()) {
+            cleanDirectory(fileOrDir);
+        }
+
+        fileOrDir.delete();
+    }
+
+    public static void cleanDirectory(File directory) throws IOException {
+        if (!directory.exists()) {
+            String message = directory + " does not exist";
+            throw new IllegalArgumentException(message);
+        }
+
+        if (!directory.isDirectory()) {
+            String message = directory + " is not a directory";
+            throw new IllegalArgumentException(message);
+        }
+
+        File[] files = directory.listFiles();
+        if (files == null) { // null if security restricted
+            throw new IOException("Failed to list contents of " + directory);
+        }
+
+        IOException exception = null;
+        for (File file : files) {
+            try {
+                delete(file);
+            } catch (IOException ioe) {
+                exception = ioe;
+            }
+        }
+
+        if (null != exception) {
+            throw exception;
+        }
+    }
+
+    public static void writeStringToFile(File file, String data, String 
encoding) throws IOException {
+        OutputStream os = null;
+        try {
+            os = new FileOutputStream(file);
+            os.write(data.getBytes(encoding));
+        } finally {
+            if (null != os) {
+                os.close();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/RpcErrorMapper.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/RpcErrorMapper.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/RpcErrorMapper.java
new file mode 100644
index 0000000..9def61d
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/RpcErrorMapper.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * Every error consists of error-latitude and error-longitude
+ */
+public class RpcErrorMapper {
+    private RpcErrorLatitude errorLatitude;
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this, 
ToStringStyle.MULTI_LINE_STYLE);
+    }
+
+    public enum RpcErrorLatitude {
+        LOCAL("01"),
+        REMOTE("02");
+
+        private static Map<String, RpcErrorLatitude> stringToEnum = new 
HashMap<String, RpcErrorLatitude>();
+
+        static {
+            for (RpcErrorLatitude el : values()) {
+                stringToEnum.put(el.getCode(), el);
+            }
+        }
+
+        private String code;
+
+        RpcErrorLatitude(String code) {
+            this.code = code;
+        }
+
+        public static RpcErrorLatitude fromString(String cdoe) {
+            return stringToEnum.get(cdoe);
+        }
+
+        public String getCode() {
+            return code;
+        }
+
+        public void setCode(String code) {
+            this.code = code;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ServiceUtil.java
----------------------------------------------------------------------
diff --git 
a/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ServiceUtil.java
 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ServiceUtil.java
new file mode 100644
index 0000000..87cefc3
--- /dev/null
+++ 
b/remoting-core/rpc-impl/src/main/java/org/apache/rocketmq/rpc/internal/ServiceUtil.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.rpc.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.rocketmq.remoting.api.serializable.Serializer;
+import 
org.apache.rocketmq.remoting.impl.protocol.serializer.SerializerFactoryImpl;
+import org.apache.rocketmq.rpc.annotation.RemoteMethod;
+import org.apache.rocketmq.rpc.annotation.RemoteService;
+import org.apache.rocketmq.rpc.impl.service.RpcEntry;
+
+public class ServiceUtil {
+    private static int methodExceptionLimit = 7;
+    private static int methodEmbeddedGenericParameterLimit = 2;
+    private static int methodSuperInterfaceLimit = 128;
+    private static int methodParameterLimit = 7;
+    private static SerializerFactoryImpl serializerFactory = new 
SerializerFactoryImpl();
+
+    public static String toRequestCode(final RemoteService sc, Method method) {
+        RemoteMethod asynchronous = method.getAnnotation(RemoteMethod.class);
+        if (asynchronous != null) {
+            return String.format("%s_%s/%s_%s", sc.name(), sc.version(),
+                asynchronous.name().isEmpty() ? sharedToString(method) : 
asynchronous.name(),
+                asynchronous.version());
+        } else
+            throw new IllegalArgumentException("RemoteMethod annotation not 
exist in method " + method.getName());
+    }
+
+    public static Set<String> getRequestCode(final Object obj) {
+        Set<String> requestCodeSet = new TreeSet<>();
+        Class<?>[] interfaces = obj.getClass().getInterfaces();
+        for (Class<?> itf : interfaces) {
+            RemoteService serviceExport = 
itf.getAnnotation(RemoteService.class);
+            if (null == serviceExport) {
+                throw new IllegalArgumentException("The Interface:" + 
itf.getName() + " do not remark RemoteService annotationType");
+            }
+
+            Method[] methods = itf.getMethods();
+            for (Method method : methods) {
+                if (method.getAnnotation(RemoteMethod.class) != null) {
+                    if (ServiceUtil.testServiceExportMethod(method)) {
+                        String requestCode = 
ServiceUtil.toRequestCode(serviceExport, method);
+                        RpcEntry se = new RpcEntry();
+                        se.setServiceExport(serviceExport);
+                        se.setObject(obj);
+                        se.setMethod(method);
+                        requestCodeSet.add(requestCode);
+                    }
+                } else {
+                    throw new IllegalArgumentException("RemoteMethod 
annotation not exist in method " + method.getName());
+                }
+            }
+        }
+
+        if (requestCodeSet.isEmpty()) {
+            throw new IllegalArgumentException("interface no method or 
interface not set annotation");
+        }
+        return requestCodeSet;
+    }
+
+    private static boolean isGenericParameterDepthMuchLimit(Type type, int 
count) {
+        if (count > methodEmbeddedGenericParameterLimit)
+            return true;
+        if (type instanceof ParameterizedType) {
+            ParameterizedType parameterizedType = (ParameterizedType) type;
+            Type[] types = parameterizedType.getActualTypeArguments();
+            boolean isGenericParameter;
+            for (final Type typ : types) {
+                isGenericParameter = isGenericParameterDepthMuchLimit(typ, 
count + 1);
+                if (isGenericParameter)
+                    return isGenericParameter;
+            }
+        }
+        return false;
+    }
+
+    private static boolean getGenericParameterTypes(Type[] types) {
+        boolean genericFlag = false;
+        for (Type type : types) {
+            genericFlag |= isGenericParameterDepthMuchLimit(type, 0);
+        }
+        return genericFlag;
+    }
+
+    private static boolean isInterfaceInHeritDepthMuchLimit(Class<?> obj, int 
count) {
+        if (count > methodSuperInterfaceLimit)
+            return true;
+        final RemoteService serviceExport = 
obj.getAnnotation(RemoteService.class);
+        if (serviceExport == null)
+            return false;
+        Class<?>[] types = obj.getInterfaces();
+        boolean isGenericParameter = false;
+        for (Class<?> type : types) {
+            isGenericParameter |= isInterfaceInHeritDepthMuchLimit(type, count 
+ 1);
+        }
+        return isGenericParameter;
+    }
+
+    private static boolean isSeriliaze(Class<?> type) {
+        return Serializable.class.isAssignableFrom(type);
+    }
+
+    public static boolean testServiceExportMethod(Method method) {
+        Class<?>[] exceptions = method.getExceptionTypes();
+        Type[] types = method.getGenericParameterTypes();
+        if (method.getParameterTypes() != null
+            && method.getParameterTypes().length > methodParameterLimit)
+            throw new IllegalArgumentException("method: " + method.getName() + 
" argument more than max limit : "
+                + methodParameterLimit);
+        if (exceptions != null && exceptions.length > methodExceptionLimit)
+            throw new IllegalArgumentException(" method: " + method.getName() 
+ " exception more than max limit : "
+                + methodExceptionLimit);
+
+        if (getGenericParameterTypes(types))
+            throw new IllegalArgumentException(" method: " + method.getName() 
+ " generic argument depth more than max limit : "
+                + methodEmbeddedGenericParameterLimit);
+
+        Class<?>[] classObjs = method.getClass().getInterfaces();
+        boolean isInterfaceHeritDepthMuch = false;
+        for (Class classObj : classObjs) {
+            isInterfaceHeritDepthMuch |= 
isInterfaceInHeritDepthMuchLimit(classObj, 0);
+        }
+        if (isInterfaceHeritDepthMuch) {
+            throw new IllegalArgumentException(" method: " + method.getName() 
+ " interface inherit depth more than max limit : "
+                + methodSuperInterfaceLimit);
+        }
+        /*
+        Class<?>[] tys = method.getParameterTypes();
+        for (Class type : tys) {
+            if (!isSeriliaze(type)) {
+                throw new IllegalArgumentException("method parameter type:" + 
type.getName() + " can not Seriliaze !");
+            }
+        }
+        */
+        return true;
+    }
+
+    private static String sharedToString(Method method) {
+        try {
+            StringBuilder sb = new StringBuilder();
+
+            String methodName = method.getName();
+            if (methodName.contains("Async")) {
+                int index = methodName.indexOf("Async");
+                methodName = methodName.substring(0, index);
+            }
+            if (methodName.contains("Oneway")) {
+                int index = methodName.indexOf("Oneway");
+                methodName = methodName.substring(0, index);
+            }
+            sb.append(methodName);
+            sb.append('<');
+
+            Class<?>[] types = method.getParameterTypes();
+            for (int j = 0; j < types.length; j++) {
+                sb.append(types[j].getCanonicalName());
+                if (j < (types.length - 1))
+                    sb.append(",");
+            }
+            sb.append('>');
+            return sb.toString();
+        } catch (Exception e) {
+            return "<" + e + ">";
+        }
+    }
+
+    private static boolean isSerializer(Object[] args, Serializer serializer) {
+        boolean success;
+        if (serializer == null)
+            return false;
+        try {
+            for (Object arg : args) {
+                serializer.encode(arg);
+            }
+            success = true;
+        } catch (Exception e) {
+            success = false;
+        }
+        return success;
+    }
+
+    private static Serializer selectSerialization(Object[] args, Serializer 
defaultSerializer) {
+        if (!isSerializer(args, defaultSerializer)) {
+            Serializer[] serializers = serializerFactory.getTables();
+            for (Serializer serializer : serializers) {
+                if (isSerializer(args, serializer))
+                    return serializer;
+            }
+        } else
+            return defaultSerializer;
+        return null;
+    }
+
+    public static Serializer selectSerializer(Object[] args, byte type) {
+        Serializer defaultSerializer = serializerFactory.get(type);
+        return ServiceUtil.selectSerialization(args, defaultSerializer);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/style/checkstyle.xml
----------------------------------------------------------------------
diff --git a/style/checkstyle.xml b/style/checkstyle.xml
new file mode 100644
index 0000000..aca6ed1
--- /dev/null
+++ b/style/checkstyle.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<!DOCTYPE module PUBLIC
+    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+    "http://www.puppycrawl.com/dtds/configuration_1_3.dtd";>
+<!--Refer 
http://checkstyle.sourceforge.net/reports/google-java-style.html#s2.2-file-encoding
 -->
+<module name="Checker">
+
+    <property name="localeLanguage" value="en"/>
+
+    <!--To configure the check to report on the first instance in each file-->
+    <module name="FileTabCharacter"/>
+
+    <!-- header -->
+    <module name="RegexpHeader">
+        <property name="header" value="/\*\nLicensed to the Apache Software 
Foundation*"/>
+        <property name="fileExtensions" value="java"/>
+    </module>
+
+    <module name="RegexpHeader">
+        <property name="header" value="#[\s]*Licensed to the Apache Software 
Foundation*"/>
+        <property name="fileExtensions" value="properties"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <!--<property name="format" value="System\.out\.println"/>-->
+        <property name="message" value="Prohibit invoking System.out.println 
in source code !"/>
+    </module>
+
+    <!--<module name="RegexpSingleline">-->
+    <!--<property name="format" value="//FIXME"/>-->
+    <!--<property name="message" value="Recommended fix FIXME task !"/>-->
+    <!--</module>-->
+
+    <module name="RegexpSingleline">
+        <property name="format" value="//TODO"/>
+        <property name="message" value="Recommended fix TODO task !"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <property name="format" value="@alibaba"/>
+        <property name="message" value="Recommended remove @alibaba keyword!"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="@taobao"/>
+        <property name="message" value="Recommended remove @taobao keyword!"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="@author"/>
+        <property name="message" value="Recommended remove @author tag in 
javadoc!"/>
+    </module>
+
+    <module name="RegexpSingleline">
+        <property name="format"
+                  
value=".*[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]+.*"/>
+        <property name="message" value="Not allow chinese character !"/>
+    </module>
+
+    <module name="FileLength">
+        <property name="max" value="3000"/>
+    </module>
+
+    <module name="TreeWalker">
+
+        <module name="UnusedImports">
+            <property name="processJavadoc" value="true"/>
+        </module>
+        <module name="RedundantImport"/>
+
+        <!--<module name="IllegalImport" />-->
+
+        <!--Checks that classes that override equals() also override 
hashCode()-->
+        <module name="EqualsHashCode"/>
+        <!--Checks for over-complicated boolean expressions. Currently finds 
code like if (topic == true), topic || true, !false, etc.-->
+        <module name="SimplifyBooleanExpression"/>
+        <module name="OneStatementPerLine"/>
+        <module name="UnnecessaryParentheses"/>
+        <!--Checks for over-complicated boolean return statements. For example 
the following code-->
+        <module name="SimplifyBooleanReturn"/>
+
+        <!--Check that the default is after all the cases in producerGroup 
switch statement-->
+        <module name="DefaultComesLast"/>
+        <!--Detects empty statements (standalone ";" semicolon)-->
+        <module name="EmptyStatement"/>
+        <!--Checks that long constants are defined with an upper ell-->
+        <module name="UpperEll"/>
+        <module name="ConstantName">
+            <property name="format" 
value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)|(^log$)"/>
+        </module>
+        <!--Checks that local, non-final variable names conform to 
producerGroup format specified by the format property-->
+        <module name="LocalVariableName"/>
+        <!--Validates identifiers for local, final variables, including catch 
parameters-->
+        <module name="LocalFinalVariableName"/>
+        <!--Validates identifiers for non-static fields-->
+        <module name="MemberName"/>
+        <!--Validates identifiers for class type parameters-->
+        <!--<module name="ClassTypeParameterName">-->
+        <!--<property name="format" value="^[A-Z0-9]*$"/>-->
+        <!--</module>-->
+        <!--Validates identifiers for method type parameters-->
+        <module name="MethodTypeParameterName">
+            <property name="format" value="^[A-Z0-9]*$"/>
+        </module>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+        <!--Checks that there are no import statements that use the * 
notation-->
+        <module name="AvoidStarImport"/>
+
+        <!--whitespace-->
+        <module name="GenericWhitespace"/>
+        <!--<module name="NoWhitespaceBefore"/>-->
+        <module name="NoWhitespaceAfter"/>
+        <module name="WhitespaceAround">
+            <property name="allowEmptyConstructors" value="true"/>
+            <property name="allowEmptyMethods" value="true"/>
+        </module>
+        <!--<module name="Indentation"/>-->
+        <module name="MethodParamPad"/>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+    </module>
+</module>

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/style/codeStyle.xml
----------------------------------------------------------------------
diff --git a/style/codeStyle.xml b/style/codeStyle.xml
new file mode 100644
index 0000000..7c7ce54
--- /dev/null
+++ b/style/codeStyle.xml
@@ -0,0 +1,143 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<code_scheme name="rocketmq">
+    <option name="USE_SAME_INDENTS" value="true"/>
+    <option name="IGNORE_SAME_INDENTS_FOR_LANGUAGES" value="true"/>
+    <option name="OTHER_INDENT_OPTIONS">
+        <value>
+            <option name="INDENT_SIZE" value="4"/>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+            <option name="TAB_SIZE" value="4"/>
+            <option name="USE_TAB_CHARACTER" value="false"/>
+            <option name="SMART_TABS" value="false"/>
+            <option name="LABEL_INDENT_SIZE" value="0"/>
+            <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+            <option name="USE_RELATIVE_INDENTS" value="false"/>
+        </value>
+    </option>
+    <option name="PREFER_LONGER_NAMES" value="false"/>
+    <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
+    <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
+    <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
+        <value/>
+    </option>
+    <option name="IMPORT_LAYOUT_TABLE">
+        <value>
+            <package name="" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="true"/>
+        </value>
+    </option>
+    <option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
+    <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
+    <option name="JD_P_AT_EMPTY_LINES" value="false"/>
+    <option name="JD_KEEP_INVALID_TAGS" value="false"/>
+    <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true"/>
+    <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+    <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+    <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+    <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+    <option name="WHILE_ON_NEW_LINE" value="true"/>
+    <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+    <option name="ALIGN_MULTILINE_FOR" value="false"/>
+    <option name="SPACE_AFTER_TYPE_CAST" value="true"/>
+    <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
+    <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+    <option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
+    <option name="LABELED_STATEMENT_WRAP" value="1"/>
+    <option name="WRAP_COMMENTS" value="true"/>
+    <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+    <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+    <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+    <JavaCodeStyleSettings>
+        <option name="CLASS_NAMES_IN_JAVADOC" value="3"/>
+    </JavaCodeStyleSettings>
+    <XML>
+        <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
+    </XML>
+    <ADDITIONAL_INDENT_OPTIONS fileType="haml">
+        <option name="INDENT_SIZE" value="2"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <codeStyleSettings language="Groovy">
+        <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+        <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+        <option name="ALIGN_MULTILINE_FOR" value="false"/>
+        <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+        <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+        <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+        <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+        <indentOptions>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+    <codeStyleSettings language="HOCON">
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+    </codeStyleSettings>
+    <codeStyleSettings language="JAVA">
+        <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+        <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="WHILE_ON_NEW_LINE" value="true"/>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+        <option name="ALIGN_MULTILINE_FOR" value="false"/>
+        <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
+        <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+        <option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
+        <option name="LABELED_STATEMENT_WRAP" value="1"/>
+        <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+        <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+        <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+        <indentOptions>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+    <codeStyleSettings language="JSON">
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+    </codeStyleSettings>
+    <codeStyleSettings language="Scala">
+        <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
+        <option name="WHILE_ON_NEW_LINE" value="true"/>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+        <option name="ALIGN_MULTILINE_FOR" value="false"/>
+        <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+        <option name="METHOD_ANNOTATION_WRAP" value="1"/>
+        <option name="CLASS_ANNOTATION_WRAP" value="1"/>
+        <option name="FIELD_ANNOTATION_WRAP" value="1"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+        <indentOptions>
+            <option name="INDENT_SIZE" value="4"/>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+            <option name="TAB_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+    <codeStyleSettings language="XML">
+        <indentOptions>
+            <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+        </indentOptions>
+    </codeStyleSettings>
+</code_scheme>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/style/copyright/Apache.xml
----------------------------------------------------------------------
diff --git a/style/copyright/Apache.xml b/style/copyright/Apache.xml
new file mode 100644
index 0000000..7ca71b5
--- /dev/null
+++ b/style/copyright/Apache.xml
@@ -0,0 +1,24 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<component name="CopyrightManager">
+    <copyright>
+        <option name="myName" value="Apache"/>
+        <option name="notice"
+                value="Licensed to the Apache Software Foundation (ASF) under 
one or more&#10;contributor license agreements.  See the NOTICE file 
distributed with&#10;this work for additional information regarding copyright 
ownership.&#10;The ASF licenses this file to You under the Apache License, 
Version 2.0&#10;(the &quot;License&quot;); you may not use this file except in 
compliance with&#10;the License.  You may obtain a copy of the License 
at&#10;&#10;    http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless 
required by applicable law or agreed to in writing, software&#10;distributed 
under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT 
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the 
License for the specific language governing permissions and&#10;limitations 
under the License."/>
+    </copyright>
+</component>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0b88e66f/style/copyright/profiles_settings.xml
----------------------------------------------------------------------
diff --git a/style/copyright/profiles_settings.xml 
b/style/copyright/profiles_settings.xml
new file mode 100644
index 0000000..d326b8c
--- /dev/null
+++ b/style/copyright/profiles_settings.xml
@@ -0,0 +1,64 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<component name="CopyrightManager">
+    <settings default="Apache">
+        <module2copyright>
+            <element module="All" copyright="Apache"/>
+        </module2copyright>
+        <LanguageOptions name="GSP">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="HTML">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="JAVA">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="addBlankAfter" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="JSP">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="JSPX">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="MXML">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="Properties">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="block" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="SPI">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="block" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="XML">
+            <option name="fileTypeOverride" value="3"/>
+            <option name="prefixLines" value="false"/>
+        </LanguageOptions>
+        <LanguageOptions name="__TEMPLATE__">
+            <option name="separateBefore" value="true"/>
+            <option name="lenBefore" value="1"/>
+        </LanguageOptions>
+    </settings>
+</component>
\ No newline at end of file

Reply via email to