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 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."/> + </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