From d95af6d4cda85f31b6b7598ec001a58073b5dc0f Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 30 May 2016 12:36:03 +0800 Subject: [PATCH 01/10] yar protocol temp --- motan-protocol-yar/pom.xml | 44 ++++++ .../motan/protocol/yar/HttpYarHandler.java | 142 ++++++++++++++++++ .../weibo/api/motan/protocol/yar/Model.java | 31 ++++ .../weibo/api/motan/protocol/yar/Test.java | 55 +++++++ .../api/motan/protocol/yar/YarExporter.java | 82 ++++++++++ .../motan/protocol/yar/YarProtocolUtil.java | 131 ++++++++++++++++ .../api/motan/protocol/yar/YarReferer.java | 79 ++++++++++ .../motan/protocol/yar/YarRpcProtocol.java | 63 ++++++++ .../api/motan/protocol/yar/YarServer.java | 105 +++++++++++++ .../services/com.weibo.api.motan.rpc.Protocol | 17 +++ 10 files changed, 749 insertions(+) create mode 100644 motan-protocol-yar/pom.xml create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java create mode 100644 motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol diff --git a/motan-protocol-yar/pom.xml b/motan-protocol-yar/pom.xml new file mode 100644 index 000000000..807466791 --- /dev/null +++ b/motan-protocol-yar/pom.xml @@ -0,0 +1,44 @@ + + + + 4.0.0 + + com.weibo + motan + 0.1.2-SNAPSHOT + + motan-protocol-yar + motan-protocol-yar + http://maven.apache.org + + UTF-8 + + + + com.weibo + motan-core + ${project.parent.version} + + + com.weibo + yar-java + 0.0.1-SNAPSHOT + + + diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java new file mode 100644 index 000000000..76585df9e --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java @@ -0,0 +1,142 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandler.Sharable; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpHeaders.Values; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadPoolExecutor; + +import com.weibo.api.motan.exception.MotanFrameworkException; +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.yar.YarProtocol; +import com.weibo.yar.YarRequest; +import com.weibo.yar.YarResponse; + +@Sharable +public class HttpYarHandler extends SimpleChannelInboundHandler { + private ThreadPoolExecutor threadPoolExecutor; + + protected ConcurrentHashMap> providerMap = new ConcurrentHashMap>(); + + + public HttpYarHandler() { + super(); + } + + public HttpYarHandler(ThreadPoolExecutor threadPoolExecutor) { + this.threadPoolExecutor = threadPoolExecutor; + } + + @Override + protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpRequest httpRequest) throws Exception { + final String path = httpRequest.getUri(); + System.out.println("request uri:" + path); + ByteBuf buf = httpRequest.content(); + final byte[] bytes = new byte[buf.readableBytes()]; + buf.getBytes(0, bytes); + + if (threadPoolExecutor == null) { + processHttpRequest(ctx, path, bytes); + } else { + threadPoolExecutor.execute(new Runnable() { + @Override + public void run() { + processHttpRequest(ctx, path, bytes); + } + }); + } + + + } + + // TODO 异常时返回默认异常 + private void processHttpRequest(ChannelHandlerContext ctx, String requestPath, byte[] requestContent) { + YarResponse yarResponse = null; + String packagerName = "JSON"; + try{ + // TODO badRequest + YarRequest yarRequest = YarProtocol.buildRequest(requestContent); + packagerName = yarRequest.getPackagerName(); + Provider provider = providerMap.get(requestPath); + if (provider == null) { + // TODO 返回默认异常 response + } + Class clazz = provider.getInterface(); + Request request = YarProtocolUtil.convert(yarRequest, clazz); + Response response = provider.call(request); + yarResponse = YarProtocolUtil.convert(response, packagerName); + }catch(Exception e){ + //TODO log + e.printStackTrace(); + yarResponse = buildDefaultErrorResponse(e.getMessage(), packagerName); + } + + //http response + try { + + FullHttpResponse httpResponse = + new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(YarProtocol + .toProtocolBytes(yarResponse))); + httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/octet-stream"); + httpResponse.headers().set(HttpHeaders.Names.CONTENT_LENGTH, httpResponse.content().readableBytes()); + //TODO need support? +// if (HttpHeaders.isKeepAlive(httpRequest)) { +// httpResponse.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); +// } + ctx.write(httpResponse); + ctx.flush(); + } catch (Exception e) { + // TODO log + e.printStackTrace(); + } + + + } + + + private YarResponse buildDefaultErrorResponse(String errMsg, String packagerName){ + YarResponse yarResponse = new YarResponse(); + yarResponse.setPackagerName(packagerName); + yarResponse.setError(errMsg); + yarResponse.setStatus("500"); //TODO 需要确定含义 + return yarResponse; + } + + + + public void addProvider(Provider provider) { + String path = YarProtocolUtil.getYarPath(provider.getUrl()); + Provider old = providerMap.putIfAbsent(path, provider); + if (old != null) { + throw new MotanFrameworkException("duplicate yar provider"); + } + } + + + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java new file mode 100644 index 000000000..5ec263f01 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java @@ -0,0 +1,31 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +public class Model { + + public String testVoid(){ + return "testVoid"; + } + + public void retVoid(){ + System.out.println("in retVoid"); + } + + public String testParams(String str, int mint, Integer bint, long mlong, Long blong, boolean mboo, Boolean bboo, float mf, Float bf){ + return str; + } +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java new file mode 100644 index 000000000..84e3a20d4 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java @@ -0,0 +1,55 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import java.lang.reflect.Method; + +import com.weibo.api.motan.exception.MotanServiceException; +import com.weibo.api.motan.util.ReflectUtil; + +public class Test { + + public static void main(String[] args) { + String methodName = "testVoid"; + + Object[] arguments = new Object[]{}; + + + Class interfaceClass = Model.class; + Method targetMethod = null; + //TODO 需要考虑每次反射代价,考虑如何缓存 + Method[] methods = interfaceClass.getDeclaredMethods(); + for (Method m : methods) { + if(m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length){ + targetMethod = m; + break; + } + } + if(targetMethod == null){ + throw new MotanServiceException("cann't find request method. method name " + methodName); + } + + System.out.println(ReflectUtil.getMethodDesc(targetMethod)); + //TODO 需要特别适配空类型 + //参数适配为java对应类型 + if(arguments != null && arguments.length > 0){ + Object[] adapterArguments = new Object[arguments.length]; + + } + + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java new file mode 100644 index 000000000..91c3ead68 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java @@ -0,0 +1,82 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import com.weibo.api.motan.rpc.Exporter; +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.URL; + +public class YarExporter implements Exporter { + protected YarServer server; + protected URL url; + protected Provider provider; + + + public YarExporter(YarServer server, URL url, Provider provider) { + this.server = server; + this.url = url; + this.provider = provider; + //TODO 验证provider提供的方法名和参数个数不能相同 + } + + @Override + public void init() { + if(!server.isOpen()){ + try { + server.open(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + @Override + public void destroy() { + server.close(); + } + + @Override + public boolean isAvailable() { + + return server.isAvailable(); + } + + @Override + public String desc() { + // TODO Auto-generated method stub + return null; + } + + @Override + public URL getUrl() { + // TODO Auto-generated method stub + return url; + } + + @Override + public Provider getProvider() { + // TODO Auto-generated method stub + return provider; + } + + @Override + public void unexport() { + // TODO Auto-generated method stub + + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java new file mode 100644 index 000000000..70a8380ca --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -0,0 +1,131 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import java.lang.reflect.Method; + +import org.apache.commons.lang3.StringUtils; + +import com.weibo.api.motan.exception.MotanBizException; +import com.weibo.api.motan.exception.MotanServiceException; +import com.weibo.api.motan.rpc.DefaultRequest; +import com.weibo.api.motan.rpc.DefaultResponse; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.util.ReflectUtil; +import com.weibo.yar.YarRequest; +import com.weibo.yar.YarResponse; + +public class YarProtocolUtil { + public static String getYarPath(URL url){ + //TODO 支持path定制,例如"/health" 包名中的点替换 + + return "/" + url.getGroup() + "/" + url.getPath(); + } + + /** + * 转换yar请求为motan rpc请求。 + * 由于php类型不敏感,故转换请求时只判断方法名和参数个数是否相等。相等时尝试转换为对应类型。 + * @param yarRequest + * @param interfaceClass + * @return + */ + public static Request convert(YarRequest yarRequest, Class interfaceClass){ + //TODO 根据接口兼容 + DefaultRequest request = new DefaultRequest(); + request.setInterfaceName(interfaceClass.getName()); + request.setMethodName(yarRequest.getMethodName()); + request.setRequestId(yarRequest.getId()); + addArguments(request, interfaceClass, yarRequest.getMethodName(), yarRequest.getParameters()); + + return request; + } + + public static YarRequest convert(Request request, Class interfaceClass, String packagerName){ + YarRequest yarRequest = new YarRequest(); + yarRequest.setId(request.getRequestId()); + yarRequest.setMethodName(request.getMethodName()); + yarRequest.setPackagerName(packagerName); + yarRequest.setParameters(request.getArguments()); + return yarRequest; + } + + public static Response convert(YarResponse yarResponse){ + DefaultResponse response = new DefaultResponse(); + response.setRequestId(yarResponse.getId()); + //TODO 如果不能明确返回对象,就统一使用jsonobject +// response.setValue(yarResponse.getValue(???)); + response.setValue(yarResponse.getRet()); + if(StringUtils.isNotBlank(yarResponse.getError())){ + response.setException(new MotanBizException(yarResponse.getError())); + } + + return response; + } + + public static YarResponse convert(Response response, String packagerName){ + YarResponse yarResponse = new YarResponse(); + yarResponse.setId(response.getRequestId()); + yarResponse.setPackagerName(packagerName); + yarResponse.setRet(response.getValue()); + if(response.getException() != null){ + yarResponse.setError(response.getException().getMessage()); + } + + return yarResponse; + } + + /** + * 给Request添加请求参数相关信息。 + * 由于php类型不敏感,所以只对方法名和参数个数做匹配,然后对参数做兼容处理 + * @param interfaceClass + * @param methodName + * @param arguments + * @return + */ + private static void addArguments(DefaultRequest request, Class interfaceClass, String methodName, Object[] arguments){ + Method targetMethod = null; + //TODO 需要考虑每次反射代价,考虑如何缓存 + Method[] methods = interfaceClass.getDeclaredMethods(); + for (Method m : methods) { + if(m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length){ + targetMethod = m; + break; + } + } + if(targetMethod == null){ + throw new MotanServiceException("cann't find request method. method name " + methodName); + } + + request.setParamtersDesc(ReflectUtil.getMethodParamDesc(targetMethod)); + //TODO 需要特别适配空类型 + //参数适配为java对应类型 + if(arguments != null && arguments.length > 0){ + Object[] adapterArguments = new Object[arguments.length]; + Class[] argumentClazz = targetMethod.getParameterTypes(); +// for (int i = 0; i < argumentClazz.length; i++) { +// +// } +// request.setArguments(adapterArguments); + request.setArguments(arguments); + } + + + } + + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java new file mode 100644 index 000000000..950b49f4a --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java @@ -0,0 +1,79 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import com.weibo.api.motan.rpc.Referer; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.rpc.URL; + +public class YarReferer implements Referer { + + @Override + public Class getInterface() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Response call(Request request) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void init() { + // TODO Auto-generated method stub + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public boolean isAvailable() { + // TODO Auto-generated method stub + return false; + } + + @Override + public String desc() { + // TODO Auto-generated method stub + return null; + } + + @Override + public URL getUrl() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int activeRefererCount() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public URL getServiceUrl() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java new file mode 100644 index 000000000..58b6c4124 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java @@ -0,0 +1,63 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import java.util.concurrent.ConcurrentHashMap; + +import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.protocol.AbstractProtocol; +import com.weibo.api.motan.rpc.Exporter; +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.Referer; +import com.weibo.api.motan.rpc.URL; + +/** + * + * @Description yar rpc protocol + * @author zhanglei + * @date 2016年5月25日 + * + */ +@SpiMeta(name = "yar") +public class YarRpcProtocol extends AbstractProtocol { + protected ConcurrentHashMap serverMap = new ConcurrentHashMap(); + + @Override + protected Exporter createExporter(Provider provider, URL url) { + // TODO Auto-generated method stub + //TODO sharechannel + YarServer server = serverMap.get(url.getPort()); + if(server == null){ + serverMap.putIfAbsent(url.getPort(), new YarServer(url)); + server = serverMap.get(url.getPort()); + } + server.addProvider(provider); + try { + server.open(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return new YarExporter(server, url, provider); + } + + @Override + protected Referer createReferer(Class clz, URL url, URL serviceUrl) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java new file mode 100644 index 000000000..a983bc0f8 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java @@ -0,0 +1,105 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.stream.ChunkedWriteHandler; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.URL; + +public class YarServer { + private final HttpYarHandler handler; + private int port; + private URL url; + private Channel channel; + private EventLoopGroup bossGroup; + private EventLoopGroup workerGroup; + + public YarServer(URL url) { + this.url = url; + handler = new HttpYarHandler(new ThreadPoolExecutor(200, 800, 15, TimeUnit.SECONDS, new ArrayBlockingQueue(500))); +// handler = new HttpYarHandler(); + port = url.getPort(); + } + + public void addProvider(Provider provicer) { + handler.addProvider(provicer); + } + + public boolean open() throws InterruptedException { + if (channel != null && channel.isOpen()) { + return true; + } + if (channel != null) { + channel.close(); + } + if (bossGroup == null) { + bossGroup = new NioEventLoopGroup(); + workerGroup = new NioEventLoopGroup(); + } + + + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); + ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); + ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); + ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); + ch.pipeline().addLast("serverHandler", handler); + } + }).option(ChannelOption.SO_BACKLOG, 1024).childOption(ChannelOption.SO_KEEPALIVE, false); + + ChannelFuture f = b.bind(port).sync(); + channel = f.channel(); + return true; + } + + public void close() { + if (channel != null) { + channel.close(); + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + workerGroup = null; + bossGroup = null; + } + } + + public boolean isOpen() { + return channel.isOpen(); + } + + public boolean isAvailable() { + // TODO active == availabe ? + return channel.isActive(); + } + +} diff --git a/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol b/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol new file mode 100644 index 000000000..1f3e41f52 --- /dev/null +++ b/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol @@ -0,0 +1,17 @@ +# +# Copyright 2009-2016 Weibo, Inc. +# +# Licensed 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. +# + +com.weibo.api.motan.protocol.yar.YarRpcProtocol \ No newline at end of file From 0099dcccb71da32a97a9ee852fefa5e4805304f5 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 1 Jun 2016 14:24:16 +0800 Subject: [PATCH 02/10] =?UTF-8?q?yar=20server=20=E5=88=9D=E6=AD=A5?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../motan/protocol/yar/HttpYarHandler.java | 142 ------------- .../weibo/api/motan/protocol/yar/Model.java | 31 --- .../weibo/api/motan/protocol/yar/Test.java | 55 ------ .../api/motan/protocol/yar/YarExporter.java | 96 ++++----- .../motan/protocol/yar/YarMessageRouter.java | 62 ++++++ .../motan/protocol/yar/YarProtocolUtil.java | 120 ++++++----- .../api/motan/protocol/yar/YarReferer.java | 72 ++----- .../motan/protocol/yar/YarRpcProtocol.java | 78 +++++--- .../api/motan/protocol/yar/YarServer.java | 105 ---------- .../netty4/http/Netty4HttpServer.java | 186 ++++++++++++++++++ .../netty4/http/NettyHttpRequestHandler.java | 115 +++++++++++ .../netty4/http/NoHeartbeatFactory.java | 35 ++++ .../netty4/yar/Netty4YarEndpointFactory.java | 45 +++++ .../netty4/yar/YarMessageHandlerWarpper.java | 98 +++++++++ ....weibo.api.motan.transport.EndpointFactory | 17 ++ ...weibo.api.motan.transport.HeartbeatFactory | 17 ++ 16 files changed, 752 insertions(+), 522 deletions(-) delete mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java delete mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java delete mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java delete mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java create mode 100644 motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory create mode 100644 motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java deleted file mode 100644 index 76585df9e..000000000 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/HttpYarHandler.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 com.weibo.api.motan.protocol.yar; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.codec.http.DefaultFullHttpResponse; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpHeaders.Values; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpVersion; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ThreadPoolExecutor; - -import com.weibo.api.motan.exception.MotanFrameworkException; -import com.weibo.api.motan.rpc.Provider; -import com.weibo.api.motan.rpc.Request; -import com.weibo.api.motan.rpc.Response; -import com.weibo.yar.YarProtocol; -import com.weibo.yar.YarRequest; -import com.weibo.yar.YarResponse; - -@Sharable -public class HttpYarHandler extends SimpleChannelInboundHandler { - private ThreadPoolExecutor threadPoolExecutor; - - protected ConcurrentHashMap> providerMap = new ConcurrentHashMap>(); - - - public HttpYarHandler() { - super(); - } - - public HttpYarHandler(ThreadPoolExecutor threadPoolExecutor) { - this.threadPoolExecutor = threadPoolExecutor; - } - - @Override - protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpRequest httpRequest) throws Exception { - final String path = httpRequest.getUri(); - System.out.println("request uri:" + path); - ByteBuf buf = httpRequest.content(); - final byte[] bytes = new byte[buf.readableBytes()]; - buf.getBytes(0, bytes); - - if (threadPoolExecutor == null) { - processHttpRequest(ctx, path, bytes); - } else { - threadPoolExecutor.execute(new Runnable() { - @Override - public void run() { - processHttpRequest(ctx, path, bytes); - } - }); - } - - - } - - // TODO 异常时返回默认异常 - private void processHttpRequest(ChannelHandlerContext ctx, String requestPath, byte[] requestContent) { - YarResponse yarResponse = null; - String packagerName = "JSON"; - try{ - // TODO badRequest - YarRequest yarRequest = YarProtocol.buildRequest(requestContent); - packagerName = yarRequest.getPackagerName(); - Provider provider = providerMap.get(requestPath); - if (provider == null) { - // TODO 返回默认异常 response - } - Class clazz = provider.getInterface(); - Request request = YarProtocolUtil.convert(yarRequest, clazz); - Response response = provider.call(request); - yarResponse = YarProtocolUtil.convert(response, packagerName); - }catch(Exception e){ - //TODO log - e.printStackTrace(); - yarResponse = buildDefaultErrorResponse(e.getMessage(), packagerName); - } - - //http response - try { - - FullHttpResponse httpResponse = - new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(YarProtocol - .toProtocolBytes(yarResponse))); - httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/octet-stream"); - httpResponse.headers().set(HttpHeaders.Names.CONTENT_LENGTH, httpResponse.content().readableBytes()); - //TODO need support? -// if (HttpHeaders.isKeepAlive(httpRequest)) { -// httpResponse.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); -// } - ctx.write(httpResponse); - ctx.flush(); - } catch (Exception e) { - // TODO log - e.printStackTrace(); - } - - - } - - - private YarResponse buildDefaultErrorResponse(String errMsg, String packagerName){ - YarResponse yarResponse = new YarResponse(); - yarResponse.setPackagerName(packagerName); - yarResponse.setError(errMsg); - yarResponse.setStatus("500"); //TODO 需要确定含义 - return yarResponse; - } - - - - public void addProvider(Provider provider) { - String path = YarProtocolUtil.getYarPath(provider.getUrl()); - Provider old = providerMap.putIfAbsent(path, provider); - if (old != null) { - throw new MotanFrameworkException("duplicate yar provider"); - } - } - - - -} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java deleted file mode 100644 index 5ec263f01..000000000 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Model.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 com.weibo.api.motan.protocol.yar; - -public class Model { - - public String testVoid(){ - return "testVoid"; - } - - public void retVoid(){ - System.out.println("in retVoid"); - } - - public String testParams(String str, int mint, Integer bint, long mlong, Long blong, boolean mboo, Boolean bboo, float mf, Float bf){ - return str; - } -} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java deleted file mode 100644 index 84e3a20d4..000000000 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/Test.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 com.weibo.api.motan.protocol.yar; - -import java.lang.reflect.Method; - -import com.weibo.api.motan.exception.MotanServiceException; -import com.weibo.api.motan.util.ReflectUtil; - -public class Test { - - public static void main(String[] args) { - String methodName = "testVoid"; - - Object[] arguments = new Object[]{}; - - - Class interfaceClass = Model.class; - Method targetMethod = null; - //TODO 需要考虑每次反射代价,考虑如何缓存 - Method[] methods = interfaceClass.getDeclaredMethods(); - for (Method m : methods) { - if(m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length){ - targetMethod = m; - break; - } - } - if(targetMethod == null){ - throw new MotanServiceException("cann't find request method. method name " + methodName); - } - - System.out.println(ReflectUtil.getMethodDesc(targetMethod)); - //TODO 需要特别适配空类型 - //参数适配为java对应类型 - if(arguments != null && arguments.length > 0){ - Object[] adapterArguments = new Object[arguments.length]; - - } - - } - -} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java index 91c3ead68..284a42a59 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java @@ -1,49 +1,52 @@ /* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; -import com.weibo.api.motan.rpc.Exporter; +import com.weibo.api.motan.common.URLParamType; +import com.weibo.api.motan.core.extension.ExtensionLoader; +import com.weibo.api.motan.rpc.AbstractExporter; import com.weibo.api.motan.rpc.Provider; import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.transport.EndpointFactory; +import com.weibo.api.motan.transport.Server; -public class YarExporter implements Exporter { - protected YarServer server; - protected URL url; - protected Provider provider; - - - public YarExporter(YarServer server, URL url, Provider provider) { - this.server = server; - this.url = url; - this.provider = provider; - //TODO 验证provider提供的方法名和参数个数不能相同 - } +/** + * + * @Description YarExporter + * @author zhanglei + * @date 2016年5月31日 + * + */ +public class YarExporter extends AbstractExporter { + protected Server server; + private YarRpcProtocol yarProtocol; - @Override - public void init() { - if(!server.isOpen()){ - try { - server.open(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + public YarExporter(URL url, Provider provider, YarRpcProtocol yarProtocol) { + super(provider, url); + EndpointFactory endpointFactory = + ExtensionLoader.getExtensionLoader(EndpointFactory.class).getExtension( + url.getParameter(URLParamType.endpointFactory.getName(), "netty4yar")); + // set noheartbeat factory + String heartbeatFactory = url.getParameter(URLParamType.heartbeatFactory.getName()); + if (heartbeatFactory == null) { + url.addParameter(URLParamType.heartbeatFactory.getName(), "noHeartbeat"); } + server = endpointFactory.createServer(url, yarProtocol.initRequestRouter(url, provider)); + // TODO 验证provider提供的方法名和参数个数不能相同 } + @Override public void destroy() { server.close(); @@ -51,32 +54,17 @@ public void destroy() { @Override public boolean isAvailable() { - return server.isAvailable(); } @Override - public String desc() { - // TODO Auto-generated method stub - return null; - } - - @Override - public URL getUrl() { - // TODO Auto-generated method stub - return url; - } - - @Override - public Provider getProvider() { - // TODO Auto-generated method stub - return provider; + public void unexport() { + yarProtocol.unexport(url, provider); } @Override - public void unexport() { - // TODO Auto-generated method stub - + protected boolean doInit() { + return server.open(); } } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java new file mode 100644 index 000000000..78a70d7e0 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java @@ -0,0 +1,62 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import java.util.concurrent.ConcurrentHashMap; + +import com.weibo.api.motan.exception.MotanFrameworkException; +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.transport.Channel; +import com.weibo.api.motan.transport.ProviderProtectedMessageRouter; +import com.weibo.yar.YarRequest; +import com.weibo.yar.YarResponse; + +public class YarMessageRouter extends ProviderProtectedMessageRouter { + protected ConcurrentHashMap> providerMap = new ConcurrentHashMap>(); + + @Override + public Object handle(Channel channel, Object message) { + YarRequest yarRequest = (YarRequest) message; + + String packagerName = yarRequest.getPackagerName(); + Provider provider = providerMap.get(yarRequest.getRequestPath()); + if (provider == null) { + // TODO 返回默认异常 response + } + Class clazz = provider.getInterface(); + Request request = YarProtocolUtil.convert(yarRequest, clazz); + Response response = call(request, provider); + YarResponse yarResponse = YarProtocolUtil.convert(response, packagerName); + return yarResponse; + } + + @Override + public void addProvider(Provider provider) { + // TODO 优先注解获取path。 + String path = YarProtocolUtil.getYarPath(provider.getUrl()); + Provider old = providerMap.putIfAbsent(path, provider); + if (old != null) { + throw new MotanFrameworkException("duplicate yar provider"); + } + } + + @Override + public void removeProvider(Provider provider) { + String path = YarProtocolUtil.getYarPath(provider.getUrl()); + providerMap.remove(path); + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java index 70a8380ca..6adb68525 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -1,17 +1,15 @@ /* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; @@ -31,31 +29,31 @@ import com.weibo.yar.YarResponse; public class YarProtocolUtil { - public static String getYarPath(URL url){ - //TODO 支持path定制,例如"/health" 包名中的点替换 - + public static String getYarPath(URL url) { + // TODO 支持path定制,例如"/health" 包名中的点替换 + return "/" + url.getGroup() + "/" + url.getPath(); } - + /** - * 转换yar请求为motan rpc请求。 - * 由于php类型不敏感,故转换请求时只判断方法名和参数个数是否相等。相等时尝试转换为对应类型。 + * 转换yar请求为motan rpc请求。 由于php类型不敏感,故转换请求时只判断方法名和参数个数是否相等。相等时尝试转换为对应类型。 + * * @param yarRequest * @param interfaceClass * @return */ - public static Request convert(YarRequest yarRequest, Class interfaceClass){ - //TODO 根据接口兼容 + public static Request convert(YarRequest yarRequest, Class interfaceClass) { + // TODO 根据接口兼容 DefaultRequest request = new DefaultRequest(); request.setInterfaceName(interfaceClass.getName()); request.setMethodName(yarRequest.getMethodName()); request.setRequestId(yarRequest.getId()); addArguments(request, interfaceClass, yarRequest.getMethodName(), yarRequest.getParameters()); - + return request; } - - public static YarRequest convert(Request request, Class interfaceClass, String packagerName){ + + public static YarRequest convert(Request request, Class interfaceClass, String packagerName) { YarRequest yarRequest = new YarRequest(); yarRequest.setId(request.getRequestId()); yarRequest.setMethodName(request.getMethodName()); @@ -63,69 +61,83 @@ public static YarRequest convert(Request request, Class interfaceClass, Strin yarRequest.setParameters(request.getArguments()); return yarRequest; } - - public static Response convert(YarResponse yarResponse){ + + public static Response convert(YarResponse yarResponse) { DefaultResponse response = new DefaultResponse(); response.setRequestId(yarResponse.getId()); - //TODO 如果不能明确返回对象,就统一使用jsonobject -// response.setValue(yarResponse.getValue(???)); + // TODO 如果不能明确返回对象,就统一使用jsonobject + // response.setValue(yarResponse.getValue(???)); response.setValue(yarResponse.getRet()); - if(StringUtils.isNotBlank(yarResponse.getError())){ + if (StringUtils.isNotBlank(yarResponse.getError())) { response.setException(new MotanBizException(yarResponse.getError())); } - + return response; } - - public static YarResponse convert(Response response, String packagerName){ + + public static YarResponse convert(Response response, String packagerName) { YarResponse yarResponse = new YarResponse(); yarResponse.setId(response.getRequestId()); yarResponse.setPackagerName(packagerName); yarResponse.setRet(response.getValue()); - if(response.getException() != null){ + if (response.getException() != null) { yarResponse.setError(response.getException().getMessage()); } - + return yarResponse; } - + /** - * 给Request添加请求参数相关信息。 - * 由于php类型不敏感,所以只对方法名和参数个数做匹配,然后对参数做兼容处理 + * 给Request添加请求参数相关信息。 由于php类型不敏感,所以只对方法名和参数个数做匹配,然后对参数做兼容处理 + * * @param interfaceClass * @param methodName * @param arguments * @return */ - private static void addArguments(DefaultRequest request, Class interfaceClass, String methodName, Object[] arguments){ + private static void addArguments(DefaultRequest request, Class interfaceClass, String methodName, Object[] arguments) { Method targetMethod = null; - //TODO 需要考虑每次反射代价,考虑如何缓存 + // TODO 需要考虑每次反射代价,考虑是否需要缓存 Method[] methods = interfaceClass.getDeclaredMethods(); for (Method m : methods) { - if(m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length){ + if (m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length) { targetMethod = m; break; } } - if(targetMethod == null){ + if (targetMethod == null) { throw new MotanServiceException("cann't find request method. method name " + methodName); } - + request.setParamtersDesc(ReflectUtil.getMethodParamDesc(targetMethod)); - //TODO 需要特别适配空类型 - //参数适配为java对应类型 - if(arguments != null && arguments.length > 0){ - Object[] adapterArguments = new Object[arguments.length]; + + if (arguments != null && arguments.length > 0) { Class[] argumentClazz = targetMethod.getParameterTypes(); -// for (int i = 0; i < argumentClazz.length; i++) { -// -// } -// request.setArguments(adapterArguments); - request.setArguments(arguments); + request.setArguments(adaptParams(arguments, argumentClazz)); } - - + + } - + + public static YarResponse buildDefaultErrorResponse(String errMsg, String packagerName) { + YarResponse yarResponse = new YarResponse(); + yarResponse.setPackagerName(packagerName); + yarResponse.setError(errMsg); + yarResponse.setStatus("500"); // TODO 需要确定含义 + return yarResponse; + } + + + // 参数适配为java对应类型 + private static Object[] adaptParams(Object[] arguments, Class[] argumentClazz) { + // TODO 需要特别适配空类型 + // Object[] adapterArguments = new Object[arguments.length]; + // for (int i = 0; i < argumentClazz.length; i++) { + // + // } + // request.setArguments(adapterArguments); + return arguments; + } + } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java index 950b49f4a..7bf8aaedc 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java @@ -1,43 +1,28 @@ /* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; -import com.weibo.api.motan.rpc.Referer; +import com.weibo.api.motan.rpc.AbstractReferer; import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.rpc.Response; import com.weibo.api.motan.rpc.URL; -public class YarReferer implements Referer { +public class YarReferer extends AbstractReferer { - @Override - public Class getInterface() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Response call(Request request) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void init() { - // TODO Auto-generated method stub - + public YarReferer(Class clz, URL url) { + super(clz, url); + // TODO Auto-generated constructor stub } @Override @@ -47,33 +32,16 @@ public void destroy() { } @Override - public boolean isAvailable() { - // TODO Auto-generated method stub - return false; - } - - @Override - public String desc() { - // TODO Auto-generated method stub - return null; - } - - @Override - public URL getUrl() { + protected Response doCall(Request request) { // TODO Auto-generated method stub return null; } @Override - public int activeRefererCount() { + protected boolean doInit() { // TODO Auto-generated method stub - return 0; - } - - @Override - public URL getServiceUrl() { - // TODO Auto-generated method stub - return null; + return false; } + } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java index 58b6c4124..74e8e2d4f 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java @@ -1,17 +1,15 @@ /* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; @@ -23,6 +21,9 @@ import com.weibo.api.motan.rpc.Provider; import com.weibo.api.motan.rpc.Referer; import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.transport.ProviderMessageRouter; +import com.weibo.api.motan.util.LoggerUtil; +import com.weibo.api.motan.util.MotanFrameworkUtil; /** * @@ -33,25 +34,12 @@ */ @SpiMeta(name = "yar") public class YarRpcProtocol extends AbstractProtocol { - protected ConcurrentHashMap serverMap = new ConcurrentHashMap(); + private ConcurrentHashMap ipPort2RequestRouter = new ConcurrentHashMap(); @Override protected Exporter createExporter(Provider provider, URL url) { - // TODO Auto-generated method stub - //TODO sharechannel - YarServer server = serverMap.get(url.getPort()); - if(server == null){ - serverMap.putIfAbsent(url.getPort(), new YarServer(url)); - server = serverMap.get(url.getPort()); - } - server.addProvider(provider); - try { - server.open(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return new YarExporter(server, url, provider); + + return new YarExporter(url, provider, this); } @Override @@ -60,4 +48,36 @@ protected Referer createReferer(Class clz, URL url, URL serviceUrl) { return null; } + public ProviderMessageRouter initRequestRouter(URL url, Provider provider) { + String ipPort = url.getServerPortStr(); + ProviderMessageRouter requestRouter = ipPort2RequestRouter.get(ipPort); + if (requestRouter == null) { + ipPort2RequestRouter.putIfAbsent(ipPort, new YarMessageRouter()); + requestRouter = ipPort2RequestRouter.get(ipPort); + } + requestRouter.addProvider(provider); + return requestRouter; + } + + public void unexport(URL url, Provider provider){ + String protocolKey = MotanFrameworkUtil.getProtocolKey(url); + String ipPort = url.getServerPortStr(); + + Exporter exporter = (Exporter) exporterMap.remove(protocolKey); + + if (exporter != null) { + exporter.destroy(); + } + + synchronized (ipPort2RequestRouter) { + ProviderMessageRouter requestRouter = ipPort2RequestRouter.get(ipPort); + + if (requestRouter != null) { + requestRouter.removeProvider(provider); + } + } + + LoggerUtil.info("yarRpcExporter unexport Success: url={}", url); + } + } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java deleted file mode 100644 index a983bc0f8..000000000 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarServer.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2009-2016 Weibo, Inc. - * - * Licensed 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 com.weibo.api.motan.protocol.yar; - -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.stream.ChunkedWriteHandler; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import com.weibo.api.motan.rpc.Provider; -import com.weibo.api.motan.rpc.URL; - -public class YarServer { - private final HttpYarHandler handler; - private int port; - private URL url; - private Channel channel; - private EventLoopGroup bossGroup; - private EventLoopGroup workerGroup; - - public YarServer(URL url) { - this.url = url; - handler = new HttpYarHandler(new ThreadPoolExecutor(200, 800, 15, TimeUnit.SECONDS, new ArrayBlockingQueue(500))); -// handler = new HttpYarHandler(); - port = url.getPort(); - } - - public void addProvider(Provider provicer) { - handler.addProvider(provicer); - } - - public boolean open() throws InterruptedException { - if (channel != null && channel.isOpen()) { - return true; - } - if (channel != null) { - channel.close(); - } - if (bossGroup == null) { - bossGroup = new NioEventLoopGroup(); - workerGroup = new NioEventLoopGroup(); - } - - - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); - ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); - ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); - ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); - ch.pipeline().addLast("serverHandler", handler); - } - }).option(ChannelOption.SO_BACKLOG, 1024).childOption(ChannelOption.SO_KEEPALIVE, false); - - ChannelFuture f = b.bind(port).sync(); - channel = f.channel(); - return true; - } - - public void close() { - if (channel != null) { - channel.close(); - workerGroup.shutdownGracefully(); - bossGroup.shutdownGracefully(); - workerGroup = null; - bossGroup = null; - } - } - - public boolean isOpen() { - return channel.isOpen(); - } - - public boolean isAvailable() { - // TODO active == availabe ? - return channel.isActive(); - } - -} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java new file mode 100644 index 000000000..ea8635605 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java @@ -0,0 +1,186 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.transport.netty4.http; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.stream.ChunkedWriteHandler; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.weibo.api.motan.common.MotanConstants; +import com.weibo.api.motan.common.URLParamType; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.transport.AbstractServer; +import com.weibo.api.motan.transport.MessageHandler; +import com.weibo.api.motan.transport.TransportException; +import com.weibo.api.motan.util.StatisticCallback; + +/** + * + * @Description netty 4 http server. + * @author zhanglei + * @date 2016年5月31日 + * + */ +// TODO 后续移到transport netty4 模块 +public class Netty4HttpServer extends AbstractServer implements StatisticCallback { + private MessageHandler messageHandler; + private URL url; + private Channel channel; + private EventLoopGroup bossGroup; + private EventLoopGroup workerGroup; + + public Netty4HttpServer(URL url, MessageHandler messageHandler) { + this.url = url; + this.messageHandler = messageHandler; + } + + + @Override + public boolean open() { + if (isAvailable()) { + return true; + } + if (channel != null) { + channel.close(); + } + if (bossGroup == null) { + bossGroup = new NioEventLoopGroup(); + workerGroup = new NioEventLoopGroup(); + } + boolean shareChannel = url.getBooleanParameter(URLParamType.shareChannel.getName(), URLParamType.shareChannel.getBooleanValue()); + // TODO 最大链接保护 + int maxServerConnection = + url.getIntParameter(URLParamType.maxServerConnection.getName(), URLParamType.maxServerConnection.getIntValue()); + int workerQueueSize = url.getIntParameter(URLParamType.workerQueueSize.getName(), 500); + + int minWorkerThread = 0, maxWorkerThread = 0; + + if (shareChannel) { + minWorkerThread = url.getIntParameter(URLParamType.minWorkerThread.getName(), MotanConstants.NETTY_SHARECHANNEL_MIN_WORKDER); + maxWorkerThread = url.getIntParameter(URLParamType.maxWorkerThread.getName(), MotanConstants.NETTY_SHARECHANNEL_MAX_WORKDER); + } else { + minWorkerThread = + url.getIntParameter(URLParamType.minWorkerThread.getName(), MotanConstants.NETTY_NOT_SHARECHANNEL_MIN_WORKDER); + maxWorkerThread = + url.getIntParameter(URLParamType.maxWorkerThread.getName(), MotanConstants.NETTY_NOT_SHARECHANNEL_MAX_WORKDER); + } + final NettyHttpRequestHandler handler = + new NettyHttpRequestHandler(this, messageHandler, new ThreadPoolExecutor(minWorkerThread, maxWorkerThread, 15, + TimeUnit.SECONDS, new ArrayBlockingQueue(workerQueueSize))); + + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); + ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); + ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); + ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); + ch.pipeline().addLast("serverHandler", handler); + } + }).option(ChannelOption.SO_BACKLOG, 1024).childOption(ChannelOption.SO_KEEPALIVE, false); + + ChannelFuture f; + try { + f = b.bind(url.getPort()).sync(); + channel = f.channel(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + + return true; + } + + @Override + public void close() { + if (channel != null) { + channel.close(); + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + workerGroup = null; + bossGroup = null; + } + } + + public boolean isOpen() { + return channel.isOpen(); + } + + @Override + public boolean isAvailable() { + return channel == null ? false : channel.isOpen(); + } + + + @Override + public boolean isBound() { + // TODO Auto-generated method stub + return false; + } + + + @Override + public Response request(Request request) throws TransportException { + // TODO Auto-generated method stub + return null; + } + + + @Override + public void close(int timeout) { + // TODO Auto-generated method stub + + } + + + @Override + public boolean isClosed() { + return !channel.isOpen(); + } + + + + @Override + public String statisticCallback() { + // TODO Auto-generated method stub + return null; + } + + + @Override + public URL getUrl() { + return url; + } + + + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java new file mode 100644 index 000000000..c89404d10 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java @@ -0,0 +1,115 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.transport.netty4.http; + +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandler.Sharable; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +import java.util.concurrent.ThreadPoolExecutor; + +import com.weibo.api.motan.transport.Channel; +import com.weibo.api.motan.transport.MessageHandler; +import com.weibo.api.motan.util.LoggerUtil; + +/** + * + * @Description http request handler for netty4 + * @author zhanglei + * @date 2016年5月31日 + * + */ + +@Sharable +public class NettyHttpRequestHandler extends SimpleChannelInboundHandler { + private Channel serverChannel; + private ThreadPoolExecutor threadPoolExecutor; + private MessageHandler messageHandler; + + public NettyHttpRequestHandler(Channel serverChannel) { + this.serverChannel = serverChannel; + } + + public NettyHttpRequestHandler(Channel serverChannel, MessageHandler messageHandler) { + this.serverChannel = serverChannel; + this.messageHandler = messageHandler; + } + + public NettyHttpRequestHandler(Channel serverChannel, MessageHandler messageHandler, ThreadPoolExecutor threadPoolExecutor) { + this.serverChannel = serverChannel; + this.messageHandler = messageHandler; + this.threadPoolExecutor = threadPoolExecutor; + } + + + @Override + protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpRequest httpRequest) throws Exception { + // TODO check badRequest + + // TODO 需要测试跨线程有没有内存无法释放的问题,如果有就使用map传递到messageHandler + httpRequest.content().retain(); + + if (threadPoolExecutor == null) { + processHttpRequest(ctx, httpRequest); + } else { + threadPoolExecutor.execute(new Runnable() { + @Override + public void run() { + processHttpRequest(ctx, httpRequest); + } + }); + } + } + + + protected void processHttpRequest(ChannelHandlerContext ctx, FullHttpRequest httpRequest) { + FullHttpResponse httpResponse = null; + try { + httpResponse = (FullHttpResponse) messageHandler.handle(serverChannel, httpRequest); + } catch (Exception e) { + LoggerUtil.error("NettyHttpHandler process http request fail.", e); + httpResponse = getDefaultErrorResponse(e.getMessage()); + } finally { + httpRequest.content().release(); + } + try { + ctx.write(httpResponse); + ctx.flush(); + } catch (Exception e) { + LoggerUtil.error("NettyHttpHandler write response fail.", e); + } + } + + public MessageHandler getMessageHandler() { + return messageHandler; + } + + public void setMessageHandler(MessageHandler messageHandler) { + this.messageHandler = messageHandler; + } + + protected FullHttpResponse getDefaultErrorResponse(String errMsg) { + FullHttpResponse errorResponse = + new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.SERVICE_UNAVAILABLE, Unpooled.wrappedBuffer(errMsg + .getBytes())); + return errorResponse; + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java new file mode 100644 index 000000000..e12e508af --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.transport.netty4.http; + +import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.exception.MotanFrameworkException; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.transport.HeartbeatFactory; +import com.weibo.api.motan.transport.MessageHandler; + +@SpiMeta(name = "noHeartbeat") +public class NoHeartbeatFactory implements HeartbeatFactory { + + @Override + public Request createRequest() { + throw new MotanFrameworkException("cann't create request in NoHeartbeatFactory"); + } + + @Override + public MessageHandler wrapMessageHandler(MessageHandler handler) { + return handler; + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java new file mode 100644 index 000000000..7633676f8 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java @@ -0,0 +1,45 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.transport.netty4.yar; + +import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.transport.Client; +import com.weibo.api.motan.transport.MessageHandler; +import com.weibo.api.motan.transport.Server; +import com.weibo.api.motan.transport.netty4.http.Netty4HttpServer; +import com.weibo.api.motan.transport.support.AbstractEndpointFactory; + +/** + * + * @Description yar endpoint factory use netty4 + * @author zhanglei + * @date 2016年5月31日 + * + */ +@SpiMeta(name = "netty4yar") +public class Netty4YarEndpointFactory extends AbstractEndpointFactory { + + @Override + protected Server innerCreateServer(URL url, MessageHandler messageHandler) { + return new Netty4HttpServer(url, new YarMessageHandlerWarpper(messageHandler)); + } + + @Override + protected Client innerCreateClient(URL url) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java new file mode 100644 index 000000000..66f93516d --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java @@ -0,0 +1,98 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.transport.netty4.yar; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpHeaders.Values; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +import java.io.IOException; + +import com.weibo.api.motan.exception.MotanFrameworkException; +import com.weibo.api.motan.protocol.yar.YarMessageRouter; +import com.weibo.api.motan.protocol.yar.YarProtocolUtil; +import com.weibo.api.motan.transport.Channel; +import com.weibo.api.motan.transport.MessageHandler; +import com.weibo.api.motan.util.LoggerUtil; +import com.weibo.yar.YarProtocol; +import com.weibo.yar.YarRequest; +import com.weibo.yar.YarResponse; + +/** + * + * @Description wrapper to process yar message + * @author zhanglei + * @date 2016年5月31日 + * + */ +public class YarMessageHandlerWarpper implements MessageHandler { + private YarMessageRouter orgHandler; + + public YarMessageHandlerWarpper(MessageHandler orgHandler) { + if (orgHandler == null) { + throw new MotanFrameworkException("messageHandler is null!"); + } + if (orgHandler instanceof YarMessageRouter) { + this.orgHandler = (YarMessageRouter) orgHandler; + } else { + throw new MotanFrameworkException("YarMessageHandlerWarper can not wrapper " + orgHandler.getClass().getSimpleName()); + } + + } + + + + @Override + public Object handle(Channel channel, Object message) { + FullHttpRequest httpRequest = (FullHttpRequest) message; + final String requestPath = httpRequest.getUri(); + YarResponse yarResponse = null; + String packagerName = "JSON"; + try { + ByteBuf buf = httpRequest.content(); + final byte[] contentBytes = new byte[buf.readableBytes()]; + buf.getBytes(0, contentBytes); + YarRequest yarRequest = YarProtocol.buildRequest(contentBytes); + yarRequest.setRequestPath(requestPath); + yarResponse = (YarResponse) orgHandler.handle(channel, yarRequest); + + } catch (Exception e) { + LoggerUtil.error("YarMessageHandlerWarpper handle yar request fail.", e); + yarResponse = YarProtocolUtil.buildDefaultErrorResponse(e.getMessage(), packagerName); + } + byte[] responseBytes; + try { + responseBytes = YarProtocol.toProtocolBytes(yarResponse); + } catch (IOException e) { + throw new MotanFrameworkException("convert yar response to bytes fail.", e); + } + FullHttpResponse httpResponse = + new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(responseBytes)); + httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/octet-stream"); + httpResponse.headers().set(HttpHeaders.Names.CONTENT_LENGTH, httpResponse.content().readableBytes()); + + if (HttpHeaders.isKeepAlive(httpRequest)) { + httpResponse.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); + } + + return httpResponse; + } + +} diff --git a/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory b/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory new file mode 100644 index 000000000..08468e386 --- /dev/null +++ b/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory @@ -0,0 +1,17 @@ +# +# Copyright 2009-2016 Weibo, Inc. +# +# Licensed 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. +# + +com.weibo.api.motan.transport.netty4.yar.Netty4YarEndpointFactory \ No newline at end of file diff --git a/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory b/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory new file mode 100644 index 000000000..2b1c9f0d1 --- /dev/null +++ b/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory @@ -0,0 +1,17 @@ +# +# Copyright 2009-2016 Weibo, Inc. +# +# Licensed 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. +# + +com.weibo.api.motan.transport.netty4.http.NoHeartbeatFactory \ No newline at end of file From a5e7377aeb335575e6ae9d6ea252e181b1098c83 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 7 Jun 2016 19:50:22 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0yarpath=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=EF=BC=9B=E6=B7=BB=E5=8A=A0=E6=9C=8D=E5=8A=A1503?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=EF=BC=9B=E5=85=BC=E5=AE=B9msgpack=E4=B8=8Eph?= =?UTF-8?q?p=E5=BA=8F=E5=88=97=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../motan/protocol/yar/YarMessageRouter.java | 8 +-- .../motan/protocol/yar/YarProtocolUtil.java | 37 ++++++----- .../protocol/yar/annotation/YarConfig.java | 39 +++++++++++ .../netty4/http/Netty4HttpServer.java | 4 +- .../netty4/http/NettyHttpRequestHandler.java | 66 ++++++++++++++++--- .../netty4/yar/YarMessageHandlerWarpper.java | 4 +- 6 files changed, 126 insertions(+), 32 deletions(-) create mode 100644 motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java index 78a70d7e0..408f38065 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java @@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.weibo.api.motan.exception.MotanFrameworkException; +import com.weibo.api.motan.exception.MotanServiceException; import com.weibo.api.motan.rpc.Provider; import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.rpc.Response; @@ -34,7 +35,7 @@ public Object handle(Channel channel, Object message) { String packagerName = yarRequest.getPackagerName(); Provider provider = providerMap.get(yarRequest.getRequestPath()); if (provider == null) { - // TODO 返回默认异常 response + throw new MotanServiceException("can nor find service provider. request path:" + yarRequest.getRequestPath()); } Class clazz = provider.getInterface(); Request request = YarProtocolUtil.convert(yarRequest, clazz); @@ -45,8 +46,7 @@ public Object handle(Channel channel, Object message) { @Override public void addProvider(Provider provider) { - // TODO 优先注解获取path。 - String path = YarProtocolUtil.getYarPath(provider.getUrl()); + String path = YarProtocolUtil.getYarPath(provider.getInterface(), provider.getUrl()); Provider old = providerMap.putIfAbsent(path, provider); if (old != null) { throw new MotanFrameworkException("duplicate yar provider"); @@ -55,7 +55,7 @@ public void addProvider(Provider provider) { @Override public void removeProvider(Provider provider) { - String path = YarProtocolUtil.getYarPath(provider.getUrl()); + String path = YarProtocolUtil.getYarPath(provider.getInterface(), provider.getUrl()); providerMap.remove(path); } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java index 6adb68525..0cf64f2b4 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -19,6 +19,7 @@ import com.weibo.api.motan.exception.MotanBizException; import com.weibo.api.motan.exception.MotanServiceException; +import com.weibo.api.motan.protocol.yar.annotation.YarConfig; import com.weibo.api.motan.rpc.DefaultRequest; import com.weibo.api.motan.rpc.DefaultResponse; import com.weibo.api.motan.rpc.Request; @@ -29,9 +30,15 @@ import com.weibo.yar.YarResponse; public class YarProtocolUtil { - public static String getYarPath(URL url) { - // TODO 支持path定制,例如"/health" 包名中的点替换 - + // 如果接口类有 + public static String getYarPath(Class interfaceClazz, URL url) { + if (interfaceClazz != null) { + YarConfig config = interfaceClazz.getAnnotation(YarConfig.class); + if (config != null && StringUtils.isNotBlank(config.path())) { + return config.path(); + } + } + // 默认使用/group/urlpath return "/" + url.getGroup() + "/" + url.getPath(); } @@ -43,13 +50,11 @@ public static String getYarPath(URL url) { * @return */ public static Request convert(YarRequest yarRequest, Class interfaceClass) { - // TODO 根据接口兼容 DefaultRequest request = new DefaultRequest(); request.setInterfaceName(interfaceClass.getName()); request.setMethodName(yarRequest.getMethodName()); request.setRequestId(yarRequest.getId()); addArguments(request, interfaceClass, yarRequest.getMethodName(), yarRequest.getParameters()); - return request; } @@ -65,8 +70,6 @@ public static YarRequest convert(Request request, Class interfaceClass, Strin public static Response convert(YarResponse yarResponse) { DefaultResponse response = new DefaultResponse(); response.setRequestId(yarResponse.getId()); - // TODO 如果不能明确返回对象,就统一使用jsonobject - // response.setValue(yarResponse.getValue(???)); response.setValue(yarResponse.getRet()); if (StringUtils.isNotBlank(yarResponse.getError())) { response.setException(new MotanBizException(yarResponse.getError())); @@ -97,7 +100,7 @@ public static YarResponse convert(Response response, String packagerName) { */ private static void addArguments(DefaultRequest request, Class interfaceClass, String methodName, Object[] arguments) { Method targetMethod = null; - // TODO 需要考虑每次反射代价,考虑是否需要缓存 + // TODO 是否需要缓存 Method[] methods = interfaceClass.getDeclaredMethods(); for (Method m : methods) { if (m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length) { @@ -123,19 +126,23 @@ public static YarResponse buildDefaultErrorResponse(String errMsg, String packag YarResponse yarResponse = new YarResponse(); yarResponse.setPackagerName(packagerName); yarResponse.setError(errMsg); - yarResponse.setStatus("500"); // TODO 需要确定含义 + yarResponse.setStatus("500"); return yarResponse; } // 参数适配为java对应类型 private static Object[] adaptParams(Object[] arguments, Class[] argumentClazz) { - // TODO 需要特别适配空类型 - // Object[] adapterArguments = new Object[arguments.length]; - // for (int i = 0; i < argumentClazz.length; i++) { - // - // } - // request.setArguments(adapterArguments); + + for (int i = 0; i < argumentClazz.length; i++) { + if (("java.lang.Double".equals(arguments[i].getClass().getName()) && "float".equals(argumentClazz[i].getName()) || "java.lang.Float" + .equals(argumentClazz[i].getName()))) { + arguments[i] = ((Double) arguments[i]).floatValue(); + } else if ("java.lang.Long".equals(arguments[i].getClass().getName()) + && ("int".equals(argumentClazz[i].getName()) || "java.lang.Integer".equals(argumentClazz[i].getName()))) { + arguments[i] = ((Long) arguments[i]).intValue(); + } + } return arguments; } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java new file mode 100644 index 000000000..df1cf24d4 --- /dev/null +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java @@ -0,0 +1,39 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @Description yar rpc 配置 + * @author zhanglei + * @date 2016年6月7日 + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface YarConfig { + /** + * yar rpc 的request path + * @return path + */ + String path() default ""; + +} diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java index ea8635605..5cf07d679 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java @@ -39,6 +39,7 @@ import com.weibo.api.motan.transport.AbstractServer; import com.weibo.api.motan.transport.MessageHandler; import com.weibo.api.motan.transport.TransportException; +import com.weibo.api.motan.util.LoggerUtil; import com.weibo.api.motan.util.StatisticCallback; /** @@ -112,8 +113,7 @@ public void initChannel(SocketChannel ch) throws Exception { f = b.bind(url.getPort()).sync(); channel = f.channel(); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + LoggerUtil.error("init http server fail.", e); return false; } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java index c89404d10..5d130b472 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java @@ -20,6 +20,8 @@ import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpHeaders.Values; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -28,6 +30,7 @@ import com.weibo.api.motan.transport.Channel; import com.weibo.api.motan.transport.MessageHandler; import com.weibo.api.motan.util.LoggerUtil; +import com.weibo.api.motan.util.MotanSwitcherUtil; /** * @@ -39,9 +42,15 @@ @Sharable public class NettyHttpRequestHandler extends SimpleChannelInboundHandler { + public static final String BAD_REQUEST = "/bad-request"; + public static final String ROOT_PATH = "/"; + public static final String STATUS_PATH = "/rpcstatus"; private Channel serverChannel; private ThreadPoolExecutor threadPoolExecutor; private MessageHandler messageHandler; + protected String swictherName = "feature.configserver.heartbeat"; + + public NettyHttpRequestHandler(Channel serverChannel) { this.serverChannel = serverChannel; @@ -61,9 +70,23 @@ public NettyHttpRequestHandler(Channel serverChannel, MessageHandler messageHand @Override protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpRequest httpRequest) throws Exception { - // TODO check badRequest + // check badRequest + if(BAD_REQUEST.equals(httpRequest.getUri())){ + sendResponse(ctx, buildDefaultResponse("bad request!", HttpResponseStatus.BAD_REQUEST)); + return; + } + + // service status + if(ROOT_PATH.equals(httpRequest.getUri()) || STATUS_PATH.equals(httpRequest.getUri())){ + if(isSwitchOpen()){// 200 + sendResponse(ctx, buildDefaultResponse("ok!", HttpResponseStatus.OK)); + }else{//503 + sendResponse(ctx, buildErrorResponse("service not available!")); + } + return; + } - // TODO 需要测试跨线程有没有内存无法释放的问题,如果有就使用map传递到messageHandler + // TODO 需要测试跨线程有没有内存无法释放的问题,如果有问题就使用map传递到messageHandler httpRequest.content().retain(); if (threadPoolExecutor == null) { @@ -85,18 +108,47 @@ protected void processHttpRequest(ChannelHandlerContext ctx, FullHttpRequest htt httpResponse = (FullHttpResponse) messageHandler.handle(serverChannel, httpRequest); } catch (Exception e) { LoggerUtil.error("NettyHttpHandler process http request fail.", e); - httpResponse = getDefaultErrorResponse(e.getMessage()); + httpResponse = buildErrorResponse(e.getMessage()); } finally { httpRequest.content().release(); } + sendResponse(ctx, httpResponse); + } + + private void sendResponse(ChannelHandlerContext ctx, FullHttpResponse httpResponse){ try { ctx.write(httpResponse); ctx.flush(); } catch (Exception e) { LoggerUtil.error("NettyHttpHandler write response fail.", e); + } finally { + // 关闭链接 + if (httpResponse == null || !Values.KEEP_ALIVE.equals(httpResponse.headers().get(HttpHeaders.Names.CONNECTION))) { + ctx.close(); + } } } - + + protected FullHttpResponse buildErrorResponse(String errMsg) { + return buildDefaultResponse(errMsg, HttpResponseStatus.SERVICE_UNAVAILABLE); + } + + protected FullHttpResponse buildDefaultResponse(String msg, HttpResponseStatus status){ + FullHttpResponse errorResponse = + new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.wrappedBuffer(msg + .getBytes())); + return errorResponse; + } + + /** + * 判断服务开关状态,关闭时返回503 + * @return + */ + protected boolean isSwitchOpen(){ + return MotanSwitcherUtil.isOpen(swictherName); + } + + public MessageHandler getMessageHandler() { return messageHandler; } @@ -105,11 +157,5 @@ public void setMessageHandler(MessageHandler messageHandler) { this.messageHandler = messageHandler; } - protected FullHttpResponse getDefaultErrorResponse(String errMsg) { - FullHttpResponse errorResponse = - new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.SERVICE_UNAVAILABLE, Unpooled.wrappedBuffer(errMsg - .getBytes())); - return errorResponse; - } } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java index 66f93516d..5d5ecd72e 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java @@ -85,11 +85,13 @@ public Object handle(Channel channel, Object message) { } FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(responseBytes)); - httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/octet-stream"); + httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/x-www-form-urlencoded"); httpResponse.headers().set(HttpHeaders.Names.CONTENT_LENGTH, httpResponse.content().readableBytes()); if (HttpHeaders.isKeepAlive(httpRequest)) { httpResponse.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); + }else{ + httpResponse.headers().set(HttpHeaders.Names.CONNECTION, Values.CLOSE); } return httpResponse; From c5339aca53208bf3b237daf3fd56ffe520358d2e Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 13 Jun 2016 11:40:08 +0800 Subject: [PATCH 04/10] send biz exception message --- .../api/motan/protocol/yar/YarExporter.java | 28 ++++++++++++++++++- .../motan/protocol/yar/YarMessageRouter.java | 8 +++++- .../motan/protocol/yar/YarProtocolUtil.java | 20 ++++++++++--- .../netty4/http/NoHeartbeatFactory.java | 8 +++++- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java index 284a42a59..712a3fa4d 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java @@ -13,8 +13,14 @@ */ package com.weibo.api.motan.protocol.yar; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + import com.weibo.api.motan.common.URLParamType; import com.weibo.api.motan.core.extension.ExtensionLoader; +import com.weibo.api.motan.exception.MotanFrameworkException; import com.weibo.api.motan.rpc.AbstractExporter; import com.weibo.api.motan.rpc.Provider; import com.weibo.api.motan.rpc.URL; @@ -42,8 +48,10 @@ public YarExporter(URL url, Provider provider, YarRpcProtocol yarProtocol) { if (heartbeatFactory == null) { url.addParameter(URLParamType.heartbeatFactory.getName(), "noHeartbeat"); } + //FIXME 弱语言类型转换可能出现歧义,暂时通过限制同名方法参数个数不能相同避免。 + validateInterface(provider.getInterface()); server = endpointFactory.createServer(url, yarProtocol.initRequestRouter(url, provider)); - // TODO 验证provider提供的方法名和参数个数不能相同 + } @@ -66,5 +74,23 @@ public void unexport() { protected boolean doInit() { return server.open(); } + + protected void validateInterface(Class interfaceClazz){ + HashMap> tempMap = new HashMap>(); + for(Method m : interfaceClazz.getDeclaredMethods()){ + if(!tempMap.containsKey(m.getName())){ + List templist = new ArrayList(); + templist.add(m.getParameterTypes().length); + tempMap.put(m.getName(), templist); + }else{ + List templist = tempMap.get(m.getName()); + if(templist.contains(m.getParameterTypes().length)){ + throw new MotanFrameworkException("in yar protocol, methods with same name must have different params size !"); + }else{ + templist.add(m.getParameterTypes().length); + } + } + } + } } diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java index 408f38065..0ed1eaa3a 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java @@ -24,7 +24,13 @@ import com.weibo.api.motan.transport.ProviderProtectedMessageRouter; import com.weibo.yar.YarRequest; import com.weibo.yar.YarResponse; - +/** + * + * @Description yar message router + * @author zhanglei + * @date 2016年6月8日 + * + */ public class YarMessageRouter extends ProviderProtectedMessageRouter { protected ConcurrentHashMap> providerMap = new ConcurrentHashMap>(); diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java index 0cf64f2b4..388a2ddc1 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -28,7 +28,13 @@ import com.weibo.api.motan.util.ReflectUtil; import com.weibo.yar.YarRequest; import com.weibo.yar.YarResponse; - +/** + * + * @Description yar protocol util. + * @author zhanglei + * @date 2016年6月8日 + * + */ public class YarProtocolUtil { // 如果接口类有 public static String getYarPath(Class interfaceClazz, URL url) { @@ -82,16 +88,21 @@ public static YarResponse convert(Response response, String packagerName) { YarResponse yarResponse = new YarResponse(); yarResponse.setId(response.getRequestId()); yarResponse.setPackagerName(packagerName); - yarResponse.setRet(response.getValue()); if (response.getException() != null) { - yarResponse.setError(response.getException().getMessage()); + if(response.getException() instanceof MotanBizException){ + yarResponse.setError(response.getException().getCause().getMessage()); + }else{ + yarResponse.setError(response.getException().getMessage()); + } + }else{ + yarResponse.setRet(response.getValue()); } return yarResponse; } /** - * 给Request添加请求参数相关信息。 由于php类型不敏感,所以只对方法名和参数个数做匹配,然后对参数做兼容处理 + * 给Request添加请求参数相关信息。 * * @param interfaceClass * @param methodName @@ -103,6 +114,7 @@ private static void addArguments(DefaultRequest request, Class interfaceClass // TODO 是否需要缓存 Method[] methods = interfaceClass.getDeclaredMethods(); for (Method m : methods) { + //FIXME 弱类型语言转换可能出现歧义,暂时通过限制同名方法参数个数不能相同避免。 if (m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length) { targetMethod = m; break; diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java index e12e508af..c17bcca78 100644 --- a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java +++ b/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java @@ -18,7 +18,13 @@ import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.transport.HeartbeatFactory; import com.weibo.api.motan.transport.MessageHandler; - +/** + * + * @Description no heartbeatFactory + * @author zhanglei + * @date 2016年6月8日 + * + */ @SpiMeta(name = "noHeartbeat") public class NoHeartbeatFactory implements HeartbeatFactory { From 9cfb5b7e3ddcd365bbe30e44563e8539a6141b45 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 13 Jun 2016 14:14:07 +0800 Subject: [PATCH 05/10] remove yar to extension --- motan-extension/pom.xml | 13 ++++----- .../motan-protocol-yar}/pom.xml | 6 ++-- .../api/motan/protocol/yar/YarExporter.java | 0 .../motan/protocol/yar/YarMessageRouter.java | 0 .../motan/protocol/yar/YarProtocolUtil.java | 0 .../api/motan/protocol/yar/YarReferer.java | 0 .../motan/protocol/yar/YarRpcProtocol.java | 0 .../protocol/yar/annotation/YarConfig.java | 0 .../netty4/http/Netty4HttpServer.java | 0 .../netty4/http/NettyHttpRequestHandler.java | 0 .../netty4/http/NoHeartbeatFactory.java | 0 .../netty4/yar/Netty4YarEndpointFactory.java | 0 .../netty4/yar/YarMessageHandlerWarpper.java | 0 .../services/com.weibo.api.motan.rpc.Protocol | 0 ....weibo.api.motan.transport.EndpointFactory | 0 ...weibo.api.motan.transport.HeartbeatFactory | 0 motan-extension/protocl-extension/pom.xml | 28 +++++++++++++++++++ .../serialization-extension/pom.xml | 2 +- 18 files changed, 38 insertions(+), 11 deletions(-) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/pom.xml (92%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory (100%) rename {motan-protocol-yar => motan-extension/protocl-extension/motan-protocol-yar}/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory (100%) create mode 100644 motan-extension/protocl-extension/pom.xml diff --git a/motan-extension/pom.xml b/motan-extension/pom.xml index 569251fc7..33066b795 100644 --- a/motan-extension/pom.xml +++ b/motan-extension/pom.xml @@ -1,4 +1,4 @@ - + - - + 4.0.0 com.weibo @@ -19,12 +17,13 @@ motan-extension motan-extension - http://maven.apache.org + https://github.com/weibocom/motan UTF-8 pom serialization-extension + protocl-extension - + \ No newline at end of file diff --git a/motan-protocol-yar/pom.xml b/motan-extension/protocl-extension/motan-protocol-yar/pom.xml similarity index 92% rename from motan-protocol-yar/pom.xml rename to motan-extension/protocl-extension/motan-protocol-yar/pom.xml index 807466791..0ad16ace2 100644 --- a/motan-protocol-yar/pom.xml +++ b/motan-extension/protocl-extension/motan-protocol-yar/pom.xml @@ -20,12 +20,12 @@ 4.0.0 com.weibo - motan + protocol-extension 0.1.2-SNAPSHOT motan-protocol-yar motan-protocol-yar - http://maven.apache.org + https://github.com/weibocom/motan UTF-8 @@ -38,7 +38,7 @@ com.weibo yar-java - 0.0.1-SNAPSHOT + 0.0.1 diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java diff --git a/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java similarity index 100% rename from motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java diff --git a/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol b/motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol similarity index 100% rename from motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol diff --git a/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory b/motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory similarity index 100% rename from motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory diff --git a/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory b/motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory similarity index 100% rename from motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory rename to motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory diff --git a/motan-extension/protocl-extension/pom.xml b/motan-extension/protocl-extension/pom.xml new file mode 100644 index 000000000..815b46ba8 --- /dev/null +++ b/motan-extension/protocl-extension/pom.xml @@ -0,0 +1,28 @@ + + + + 4.0.0 + + com.weibo + motan-extension + 0.1.2-SNAPSHOT + + protocol-extension + protocol-extension + https://github.com/weibocom/motan + + UTF-8 + + pom + + motan-protocol-yar + + \ No newline at end of file diff --git a/motan-extension/serialization-extension/pom.xml b/motan-extension/serialization-extension/pom.xml index 2c074eafc..9c8bb03e1 100644 --- a/motan-extension/serialization-extension/pom.xml +++ b/motan-extension/serialization-extension/pom.xml @@ -19,7 +19,7 @@ serialization-extension serialization-extension - http://maven.apache.org + https://github.com/weibocom/motan UTF-8 From 21a8aec21e42ffe5dbae0430c37505f6a8942313 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 17 Jun 2016 10:51:54 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E5=85=BC=E5=AE=B9=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E5=BD=A2=E5=8F=82=E6=8E=A5=E5=8F=97=E5=AD=97=E7=AC=A6=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/motan/protocol/yar/YarExporter.java | 2 +- .../motan/protocol/yar/YarProtocolUtil.java | 68 ++++++++++++++++--- .../netty4/http/NettyHttpRequestHandler.java | 1 - 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java index 712a3fa4d..e6b716726 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java @@ -48,7 +48,7 @@ public YarExporter(URL url, Provider provider, YarRpcProtocol yarProtocol) { if (heartbeatFactory == null) { url.addParameter(URLParamType.heartbeatFactory.getName(), "noHeartbeat"); } - //FIXME 弱语言类型转换可能出现歧义,暂时通过限制同名方法参数个数不能相同避免。 + //FIXME 弱类型语言转换可能出现歧义,暂时通过限制同名方法参数个数不能相同避免。 validateInterface(provider.getInterface()); server = endpointFactory.createServer(url, yarProtocol.initRequestRouter(url, provider)); diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java index 388a2ddc1..e7fd2c13e 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -128,7 +128,7 @@ private static void addArguments(DefaultRequest request, Class interfaceClass if (arguments != null && arguments.length > 0) { Class[] argumentClazz = targetMethod.getParameterTypes(); - request.setArguments(adaptParams(arguments, argumentClazz)); + request.setArguments(adaptParams(targetMethod, arguments, argumentClazz)); } @@ -144,15 +144,65 @@ public static YarResponse buildDefaultErrorResponse(String errMsg, String packag // 参数适配为java对应类型 - private static Object[] adaptParams(Object[] arguments, Class[] argumentClazz) { - + private static Object[] adaptParams(Method method, Object[] arguments, Class[] argumentClazz) { + //FIXME php调用时,如果不显示使用数字类型,参数可能为string,需要对java类型做兼容。 + //形参可能是基本类型或对象,实参一定是对象。有没有更优雅的兼容方式? for (int i = 0; i < argumentClazz.length; i++) { - if (("java.lang.Double".equals(arguments[i].getClass().getName()) && "float".equals(argumentClazz[i].getName()) || "java.lang.Float" - .equals(argumentClazz[i].getName()))) { - arguments[i] = ((Double) arguments[i]).floatValue(); - } else if ("java.lang.Long".equals(arguments[i].getClass().getName()) - && ("int".equals(argumentClazz[i].getName()) || "java.lang.Integer".equals(argumentClazz[i].getName()))) { - arguments[i] = ((Long) arguments[i]).intValue(); + try{ + if("int".equals(argumentClazz[i].getName()) || "java.lang.Integer".equals(argumentClazz[i].getName())){ + if(arguments[i] == null){ + arguments[i] = 0;//default + }else if(arguments[i] instanceof String){ + arguments[i] = Integer.parseInt((String) arguments[i]); + }else if(arguments[i] instanceof Number){ + arguments[i] = ((Number)arguments[i]).intValue(); + }else{ + throw new RuntimeException(); + } + } else if("long".equals(argumentClazz[i].getName()) || "java.lang.Long".equals(argumentClazz[i].getName())){ + if(arguments[i] == null){ + arguments[i] = 0;//default + }else if(arguments[i] instanceof String){ + arguments[i] = Long.parseLong((String) arguments[i]); + }else if(arguments[i] instanceof Number){ + arguments[i] = ((Number)arguments[i]).longValue(); + }else{ + throw new RuntimeException(); + } + }else if("float".equals(argumentClazz[i].getName()) || "java.lang.Float".equals(argumentClazz[i].getName())){ + if(arguments[i] == null){ + arguments[i] = 0.0f;//default + }else if(arguments[i] instanceof String){ + arguments[i] = Float.parseFloat((String) arguments[i]); + }else if(arguments[i] instanceof Number){ + arguments[i] = ((Number)arguments[i]).floatValue(); + }else{ + throw new RuntimeException(); + } + }else if("double".equals(argumentClazz[i].getName()) || "java.lang.Double".equals(argumentClazz[i].getName())){ + if(arguments[i] == null){ + arguments[i] = 0.0f;//default + }else if(arguments[i] instanceof String){ + arguments[i] = Double.parseDouble((String) arguments[i]); + }else if(arguments[i] instanceof Number){ + arguments[i] = ((Number)arguments[i]).doubleValue(); + }else{ + throw new RuntimeException(); + } + }else if("boolean".equals(argumentClazz[i].getName()) || "java.lang.Boolean".equals(argumentClazz[i].getName())){ + if(arguments[i] instanceof Boolean){ + continue; + } + if(arguments[i] instanceof String){ + arguments[i] = Boolean.valueOf(((String) arguments[i])); + }else { + throw new RuntimeException(); + } + } + }catch(Exception e){ + throw new MotanServiceException("adapt param fail! method:" + method.toString() + + ", require param:" + argumentClazz[i].getName() + + ", actual param:" + (arguments[i] == null ? null : arguments[i].getClass().getName() + "-" + arguments[i])); } } return arguments; diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java index 5d130b472..383f67a31 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java @@ -86,7 +86,6 @@ protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpReque return; } - // TODO 需要测试跨线程有没有内存无法释放的问题,如果有问题就使用map传递到messageHandler httpRequest.content().retain(); if (threadPoolExecutor == null) { From f812e2508fbdfb156fd707b03d36d30502d5d672 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 26 Jul 2016 20:28:34 +0800 Subject: [PATCH 07/10] support attachment --- .../motan-protocol-yar/pom.xml | 2 +- .../motan/protocol/yar/AttachmentRequest.java | 56 +++++++++++++++++++ .../motan/protocol/yar/YarProtocolUtil.java | 3 + .../netty4/http/NettyHttpRequestHandler.java | 18 ++++-- .../netty4/yar/YarMessageHandlerWarpper.java | 32 ++++++++++- motan-extension/protocl-extension/pom.xml | 2 +- 6 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java diff --git a/motan-extension/protocl-extension/motan-protocol-yar/pom.xml b/motan-extension/protocl-extension/motan-protocol-yar/pom.xml index 0ad16ace2..6f2cddf93 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/pom.xml +++ b/motan-extension/protocl-extension/motan-protocol-yar/pom.xml @@ -21,7 +21,7 @@ com.weibo protocol-extension - 0.1.2-SNAPSHOT + 0.1.3-SNAPSHOT motan-protocol-yar motan-protocol-yar diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java new file mode 100644 index 000000000..f50528008 --- /dev/null +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import java.util.Map; + +import com.weibo.yar.YarRequest; + +/** + * + * @Description YarRequest with attachments. rpc attachments such as auth,application can pass with + * this class. + * @author zhanglei + * @date 2016年7月26日 + * + */ +public class AttachmentRequest extends YarRequest { + private Map attachments; + + public AttachmentRequest(String packagerName, String methodName, Object[] parameters) { + super(packagerName, methodName, parameters); + } + + public AttachmentRequest(long id, String packagerName, String methodName, Object[] parameters) { + super(id, packagerName, methodName, parameters); + } + + public AttachmentRequest() { + super(); + } + + public AttachmentRequest(YarRequest yarRequest, Map attachments) { + this(yarRequest.getId(), yarRequest.getPackagerName(), yarRequest.getMethodName(), yarRequest.getParameters()); + this.attachments = attachments; + } + + public Map getAttachments() { + return attachments; + } + + public void setAttachments(Map attachments) { + this.attachments = attachments; + } + +} diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java index e7fd2c13e..076066af1 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -61,6 +61,9 @@ public static Request convert(YarRequest yarRequest, Class interfaceClass) { request.setMethodName(yarRequest.getMethodName()); request.setRequestId(yarRequest.getId()); addArguments(request, interfaceClass, yarRequest.getMethodName(), yarRequest.getParameters()); + if(yarRequest instanceof AttachmentRequest){ + request.setAttachments(((AttachmentRequest)yarRequest).getAttachments()); + } return request; } diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java index 383f67a31..bda25587d 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java @@ -91,12 +91,18 @@ protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpReque if (threadPoolExecutor == null) { processHttpRequest(ctx, httpRequest); } else { - threadPoolExecutor.execute(new Runnable() { - @Override - public void run() { - processHttpRequest(ctx, httpRequest); - } - }); + try{ + threadPoolExecutor.execute(new Runnable() { + @Override + public void run() { + processHttpRequest(ctx, httpRequest); + } + }); + }catch(Exception e){ + LoggerUtil.error("request is rejected by threadpool!", e); + httpRequest.content().release(); + sendResponse(ctx, buildErrorResponse("request is rejected by threadpool!")); + } } } diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java index 5d5ecd72e..e8653d175 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java @@ -24,8 +24,11 @@ import io.netty.handler.codec.http.HttpVersion; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import com.weibo.api.motan.exception.MotanFrameworkException; +import com.weibo.api.motan.protocol.yar.AttachmentRequest; import com.weibo.api.motan.protocol.yar.YarMessageRouter; import com.weibo.api.motan.protocol.yar.YarProtocolUtil; import com.weibo.api.motan.transport.Channel; @@ -62,14 +65,23 @@ public YarMessageHandlerWarpper(MessageHandler orgHandler) { @Override public Object handle(Channel channel, Object message) { FullHttpRequest httpRequest = (FullHttpRequest) message; - final String requestPath = httpRequest.getUri(); + String uri = httpRequest.getUri(); + int index = uri.indexOf("?");// should not be null + String requestPath = uri; + Map attachments = null; + if (index > -1) { + requestPath = uri.substring(0, index); + if (index != uri.length() - 1) { + attachments = getAttachMents(uri.substring(index + 1, uri.length())); + } + } YarResponse yarResponse = null; String packagerName = "JSON"; try { ByteBuf buf = httpRequest.content(); final byte[] contentBytes = new byte[buf.readableBytes()]; buf.getBytes(0, contentBytes); - YarRequest yarRequest = YarProtocol.buildRequest(contentBytes); + YarRequest yarRequest = new AttachmentRequest(YarProtocol.buildRequest(contentBytes), attachments); yarRequest.setRequestPath(requestPath); yarResponse = (YarResponse) orgHandler.handle(channel, yarRequest); @@ -90,11 +102,25 @@ public Object handle(Channel channel, Object message) { if (HttpHeaders.isKeepAlive(httpRequest)) { httpResponse.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); - }else{ + } else { httpResponse.headers().set(HttpHeaders.Names.CONNECTION, Values.CLOSE); } return httpResponse; } + private Map getAttachMents(String params) { + Map map = new HashMap(); + String[] paramArray = params.split("&"); + for (String param : paramArray) { + String[] kv = param.split("="); + if (kv.length == 2) { + map.put(kv[0], kv[1]); + } else { + LoggerUtil.warn("yar attachment parse fail. uri param:" + param); + } + } + return map; + } + } diff --git a/motan-extension/protocl-extension/pom.xml b/motan-extension/protocl-extension/pom.xml index 815b46ba8..7449120c0 100644 --- a/motan-extension/protocl-extension/pom.xml +++ b/motan-extension/protocl-extension/pom.xml @@ -13,7 +13,7 @@ com.weibo motan-extension - 0.1.2-SNAPSHOT + 0.1.3-SNAPSHOT protocol-extension protocol-extension From c1b1e8c5b913b7b9f5c1ca033362be19702e03d7 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 28 Jul 2016 16:15:37 +0800 Subject: [PATCH 08/10] add UT --- .../loadbalance/LocalFirstLoadBalance.java | 2 +- .../api/motan/protocol/yar/YarExporter.java | 19 ++- .../motan/protocol/yar/YarMessageRouter.java | 2 +- .../motan/protocol/yar/YarProtocolUtil.java | 108 ++++++------ .../netty4/http/Netty4HttpServer.java | 58 ++++--- .../netty4/http/NettyHttpRequestHandler.java | 11 +- .../protocol/yar/YarMessageRouterTest.java | 106 ++++++++++++ .../protocol/yar/YarProtocolUtilTest.java | 154 +++++++++++++++++ .../protocol/yar/YarRpcProtocolTest.java | 72 ++++++++ .../http/NettyHttpRequestHandlerTest.java | 152 +++++++++++++++++ .../yar/YarMessageHandlerWarpperTest.java | 156 ++++++++++++++++++ 11 files changed, 749 insertions(+), 91 deletions(-) create mode 100644 motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarMessageRouterTest.java create mode 100644 motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java create mode 100644 motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java create mode 100644 motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java create mode 100644 motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java diff --git a/motan-core/src/main/java/com/weibo/api/motan/cluster/loadbalance/LocalFirstLoadBalance.java b/motan-core/src/main/java/com/weibo/api/motan/cluster/loadbalance/LocalFirstLoadBalance.java index 5feb02104..479fd13c7 100644 --- a/motan-core/src/main/java/com/weibo/api/motan/cluster/loadbalance/LocalFirstLoadBalance.java +++ b/motan-core/src/main/java/com/weibo/api/motan/cluster/loadbalance/LocalFirstLoadBalance.java @@ -69,7 +69,7 @@ protected Referer doSelect(Request request) { List> localReferers = searchLocalReferer(referers, NetUtils.getLocalAddress().getHostAddress()); - if (localReferers.isEmpty()) { + if (!localReferers.isEmpty()) { referers = localReferers; } diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java index e6b716726..83022ff88 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java @@ -48,10 +48,11 @@ public YarExporter(URL url, Provider provider, YarRpcProtocol yarProtocol) { if (heartbeatFactory == null) { url.addParameter(URLParamType.heartbeatFactory.getName(), "noHeartbeat"); } - //FIXME 弱类型语言转换可能出现歧义,暂时通过限制同名方法参数个数不能相同避免。 + // FIXME to avoid parameters ambiguous in weak type language,parameters size of method with + // same name must be different. validateInterface(provider.getInterface()); server = endpointFactory.createServer(url, yarProtocol.initRequestRouter(url, provider)); - + } @@ -74,19 +75,19 @@ public void unexport() { protected boolean doInit() { return server.open(); } - - protected void validateInterface(Class interfaceClazz){ + + protected void validateInterface(Class interfaceClazz) { HashMap> tempMap = new HashMap>(); - for(Method m : interfaceClazz.getDeclaredMethods()){ - if(!tempMap.containsKey(m.getName())){ + for (Method m : interfaceClazz.getDeclaredMethods()) { + if (!tempMap.containsKey(m.getName())) { List templist = new ArrayList(); templist.add(m.getParameterTypes().length); tempMap.put(m.getName(), templist); - }else{ + } else { List templist = tempMap.get(m.getName()); - if(templist.contains(m.getParameterTypes().length)){ + if (templist.contains(m.getParameterTypes().length)) { throw new MotanFrameworkException("in yar protocol, methods with same name must have different params size !"); - }else{ + } else { templist.add(m.getParameterTypes().length); } } diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java index 0ed1eaa3a..f1e01e345 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java @@ -41,7 +41,7 @@ public Object handle(Channel channel, Object message) { String packagerName = yarRequest.getPackagerName(); Provider provider = providerMap.get(yarRequest.getRequestPath()); if (provider == null) { - throw new MotanServiceException("can nor find service provider. request path:" + yarRequest.getRequestPath()); + throw new MotanServiceException("can not find service provider. request path:" + yarRequest.getRequestPath()); } Class clazz = provider.getInterface(); Request request = YarProtocolUtil.convert(yarRequest, clazz); diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java index 076066af1..d21be794d 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -28,15 +28,16 @@ import com.weibo.api.motan.util.ReflectUtil; import com.weibo.yar.YarRequest; import com.weibo.yar.YarResponse; + /** * - * @Description yar protocol util. + * @Description yar protocol util. * @author zhanglei * @date 2016年6月8日 * */ public class YarProtocolUtil { - // 如果接口类有 + public static String getYarPath(Class interfaceClazz, URL url) { if (interfaceClazz != null) { YarConfig config = interfaceClazz.getAnnotation(YarConfig.class); @@ -44,12 +45,12 @@ public static String getYarPath(Class interfaceClazz, URL url) { return config.path(); } } - // 默认使用/group/urlpath + // '/group/urlpath' as default return "/" + url.getGroup() + "/" + url.getPath(); } /** - * 转换yar请求为motan rpc请求。 由于php类型不敏感,故转换请求时只判断方法名和参数个数是否相等。相等时尝试转换为对应类型。 + * convert yar request to motan rpc request * * @param yarRequest * @param interfaceClass @@ -61,13 +62,13 @@ public static Request convert(YarRequest yarRequest, Class interfaceClass) { request.setMethodName(yarRequest.getMethodName()); request.setRequestId(yarRequest.getId()); addArguments(request, interfaceClass, yarRequest.getMethodName(), yarRequest.getParameters()); - if(yarRequest instanceof AttachmentRequest){ - request.setAttachments(((AttachmentRequest)yarRequest).getAttachments()); + if (yarRequest instanceof AttachmentRequest) { + request.setAttachments(((AttachmentRequest) yarRequest).getAttachments()); } return request; } - public static YarRequest convert(Request request, Class interfaceClass, String packagerName) { + public static YarRequest convert(Request request, String packagerName) { YarRequest yarRequest = new YarRequest(); yarRequest.setId(request.getRequestId()); yarRequest.setMethodName(request.getMethodName()); @@ -92,12 +93,12 @@ public static YarResponse convert(Response response, String packagerName) { yarResponse.setId(response.getRequestId()); yarResponse.setPackagerName(packagerName); if (response.getException() != null) { - if(response.getException() instanceof MotanBizException){ + if (response.getException() instanceof MotanBizException) { yarResponse.setError(response.getException().getCause().getMessage()); - }else{ + } else { yarResponse.setError(response.getException().getMessage()); } - }else{ + } else { yarResponse.setRet(response.getValue()); } @@ -105,7 +106,7 @@ public static YarResponse convert(Response response, String packagerName) { } /** - * 给Request添加请求参数相关信息。 + * add arguments * * @param interfaceClass * @param methodName @@ -114,10 +115,10 @@ public static YarResponse convert(Response response, String packagerName) { */ private static void addArguments(DefaultRequest request, Class interfaceClass, String methodName, Object[] arguments) { Method targetMethod = null; - // TODO 是否需要缓存 Method[] methods = interfaceClass.getDeclaredMethods(); for (Method m : methods) { - //FIXME 弱类型语言转换可能出现歧义,暂时通过限制同名方法参数个数不能相同避免。 + // FIXME parameters may be ambiguous in weak type language, temporarily by limiting the + // size of parameters with same method name to avoid. if (m.getName().equalsIgnoreCase(methodName) && m.getParameterTypes().length == arguments.length) { targetMethod = m; break; @@ -146,66 +147,67 @@ public static YarResponse buildDefaultErrorResponse(String errMsg, String packag } - // 参数适配为java对应类型 + // adapt parameters to java class type private static Object[] adaptParams(Method method, Object[] arguments, Class[] argumentClazz) { - //FIXME php调用时,如果不显示使用数字类型,参数可能为string,需要对java类型做兼容。 - //形参可能是基本类型或对象,实参一定是对象。有没有更优雅的兼容方式? + // FIXME the real parameter type may not same with formal parameter, for instance, formal + // parameter type is int, the real parameter maybe use String in php + // any elegant way? for (int i = 0; i < argumentClazz.length; i++) { - try{ - if("int".equals(argumentClazz[i].getName()) || "java.lang.Integer".equals(argumentClazz[i].getName())){ - if(arguments[i] == null){ - arguments[i] = 0;//default - }else if(arguments[i] instanceof String){ + try { + if ("int".equals(argumentClazz[i].getName()) || "java.lang.Integer".equals(argumentClazz[i].getName())) { + if (arguments[i] == null) { + arguments[i] = 0;// default + } else if (arguments[i] instanceof String) { arguments[i] = Integer.parseInt((String) arguments[i]); - }else if(arguments[i] instanceof Number){ - arguments[i] = ((Number)arguments[i]).intValue(); - }else{ + } else if (arguments[i] instanceof Number) { + arguments[i] = ((Number) arguments[i]).intValue(); + } else { throw new RuntimeException(); } - } else if("long".equals(argumentClazz[i].getName()) || "java.lang.Long".equals(argumentClazz[i].getName())){ - if(arguments[i] == null){ - arguments[i] = 0;//default - }else if(arguments[i] instanceof String){ + } else if ("long".equals(argumentClazz[i].getName()) || "java.lang.Long".equals(argumentClazz[i].getName())) { + if (arguments[i] == null) { + arguments[i] = 0;// default + } else if (arguments[i] instanceof String) { arguments[i] = Long.parseLong((String) arguments[i]); - }else if(arguments[i] instanceof Number){ - arguments[i] = ((Number)arguments[i]).longValue(); - }else{ + } else if (arguments[i] instanceof Number) { + arguments[i] = ((Number) arguments[i]).longValue(); + } else { throw new RuntimeException(); } - }else if("float".equals(argumentClazz[i].getName()) || "java.lang.Float".equals(argumentClazz[i].getName())){ - if(arguments[i] == null){ - arguments[i] = 0.0f;//default - }else if(arguments[i] instanceof String){ + } else if ("float".equals(argumentClazz[i].getName()) || "java.lang.Float".equals(argumentClazz[i].getName())) { + if (arguments[i] == null) { + arguments[i] = 0.0f;// default + } else if (arguments[i] instanceof String) { arguments[i] = Float.parseFloat((String) arguments[i]); - }else if(arguments[i] instanceof Number){ - arguments[i] = ((Number)arguments[i]).floatValue(); - }else{ + } else if (arguments[i] instanceof Number) { + arguments[i] = ((Number) arguments[i]).floatValue(); + } else { throw new RuntimeException(); } - }else if("double".equals(argumentClazz[i].getName()) || "java.lang.Double".equals(argumentClazz[i].getName())){ - if(arguments[i] == null){ - arguments[i] = 0.0f;//default - }else if(arguments[i] instanceof String){ + } else if ("double".equals(argumentClazz[i].getName()) || "java.lang.Double".equals(argumentClazz[i].getName())) { + if (arguments[i] == null) { + arguments[i] = 0.0f;// default + } else if (arguments[i] instanceof String) { arguments[i] = Double.parseDouble((String) arguments[i]); - }else if(arguments[i] instanceof Number){ - arguments[i] = ((Number)arguments[i]).doubleValue(); - }else{ + } else if (arguments[i] instanceof Number) { + arguments[i] = ((Number) arguments[i]).doubleValue(); + } else { throw new RuntimeException(); } - }else if("boolean".equals(argumentClazz[i].getName()) || "java.lang.Boolean".equals(argumentClazz[i].getName())){ - if(arguments[i] instanceof Boolean){ + } else if ("boolean".equals(argumentClazz[i].getName()) || "java.lang.Boolean".equals(argumentClazz[i].getName())) { + if (arguments[i] instanceof Boolean) { continue; } - if(arguments[i] instanceof String){ + if (arguments[i] instanceof String) { arguments[i] = Boolean.valueOf(((String) arguments[i])); - }else { + } else { throw new RuntimeException(); } } - }catch(Exception e){ - throw new MotanServiceException("adapt param fail! method:" + method.toString() - + ", require param:" + argumentClazz[i].getName() - + ", actual param:" + (arguments[i] == null ? null : arguments[i].getClass().getName() + "-" + arguments[i])); + } catch (Exception e) { + throw new MotanServiceException("adapt param fail! method:" + method.toString() + ", require param:" + + argumentClazz[i].getName() + ", actual param:" + + (arguments[i] == null ? null : arguments[i].getClass().getName() + "-" + arguments[i])); } } return arguments; diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java index 5cf07d679..519e6bd6e 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java @@ -31,8 +31,10 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import com.weibo.api.motan.common.ChannelState; import com.weibo.api.motan.common.MotanConstants; import com.weibo.api.motan.common.URLParamType; +import com.weibo.api.motan.exception.MotanFrameworkException; import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.rpc.Response; import com.weibo.api.motan.rpc.URL; @@ -41,6 +43,7 @@ import com.weibo.api.motan.transport.TransportException; import com.weibo.api.motan.util.LoggerUtil; import com.weibo.api.motan.util.StatisticCallback; +import com.weibo.api.motan.util.StatsUtil; /** * @@ -76,7 +79,7 @@ public boolean open() { workerGroup = new NioEventLoopGroup(); } boolean shareChannel = url.getBooleanParameter(URLParamType.shareChannel.getName(), URLParamType.shareChannel.getBooleanValue()); - // TODO 最大链接保护 + // TODO max connection protect int maxServerConnection = url.getIntParameter(URLParamType.maxServerConnection.getName(), URLParamType.maxServerConnection.getIntValue()); int workerQueueSize = url.getIntParameter(URLParamType.workerQueueSize.getName(), 500); @@ -92,6 +95,7 @@ public boolean open() { maxWorkerThread = url.getIntParameter(URLParamType.maxWorkerThread.getName(), MotanConstants.NETTY_NOT_SHARECHANNEL_MAX_WORKDER); } + final int maxContentLength = url.getIntParameter(URLParamType.maxContentLength.getName(), URLParamType.maxContentLength.getIntValue()); final NettyHttpRequestHandler handler = new NettyHttpRequestHandler(this, messageHandler, new ThreadPoolExecutor(minWorkerThread, maxWorkerThread, 15, TimeUnit.SECONDS, new ArrayBlockingQueue(workerQueueSize))); @@ -101,7 +105,7 @@ public boolean open() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); - ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); + ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(maxContentLength)); ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); ch.pipeline().addLast("serverHandler", handler); @@ -116,62 +120,70 @@ public void initChannel(SocketChannel ch) throws Exception { LoggerUtil.error("init http server fail.", e); return false; } - + state = ChannelState.ALIVE; + StatsUtil.registryStatisticCallback(this); + LoggerUtil.info("Netty4HttpServer ServerChannel finish Open: url=" + url); return true; } @Override public void close() { - if (channel != null) { - channel.close(); - workerGroup.shutdownGracefully(); - bossGroup.shutdownGracefully(); - workerGroup = null; - bossGroup = null; - } - } - - public boolean isOpen() { - return channel.isOpen(); + close(0); } @Override public boolean isAvailable() { - return channel == null ? false : channel.isOpen(); + return state.isAliveState(); } @Override public boolean isBound() { - // TODO Auto-generated method stub - return false; + return channel != null && channel.isActive(); } @Override public Response request(Request request) throws TransportException { - // TODO Auto-generated method stub - return null; + throw new MotanFrameworkException("Netty4HttpServer request(Request request) method unsupport: url: " + url); } @Override public void close(int timeout) { - // TODO Auto-generated method stub - + if (state.isCloseState()) { + LoggerUtil.info("NettyServer close fail: already close, url={}", url.getUri()); + return; + } + + if (state.isUnInitState()) { + LoggerUtil.info("NettyServer close Fail: don't need to close because node is unInit state: url={}", + url.getUri()); + return; + } + if (channel != null) { + channel.close(); + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + workerGroup = null; + bossGroup = null; + } + state = ChannelState.CLOSE; + + StatsUtil.unRegistryStatisticCallback(this); } @Override public boolean isClosed() { - return !channel.isOpen(); + return state.isCloseState(); } @Override public String statisticCallback() { - // TODO Auto-generated method stub + //TODO return null; } diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java index bda25587d..46029d915 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java @@ -27,6 +27,7 @@ import java.util.concurrent.ThreadPoolExecutor; +import com.weibo.api.motan.common.MotanConstants; import com.weibo.api.motan.transport.Channel; import com.weibo.api.motan.transport.MessageHandler; import com.weibo.api.motan.util.LoggerUtil; @@ -48,7 +49,7 @@ public class NettyHttpRequestHandler extends SimpleChannelInboundHandler provider) { + return response; + } + + } + + @YarConfig(path = "/test/anno_path") + interface AnnoService { + String hello(String name); + } + + interface normalService { + String hello(String name); + } +} diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java new file mode 100644 index 000000000..5f6bdadaf --- /dev/null +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java @@ -0,0 +1,154 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.lang.reflect.Method; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.weibo.api.motan.exception.MotanBizException; +import com.weibo.api.motan.rpc.DefaultRequest; +import com.weibo.api.motan.rpc.DefaultResponse; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.util.ReflectUtil; +import com.weibo.yar.YarRequest; +import com.weibo.yar.YarResponse; + +/** + * + * @Description YarProtocolUtilTest + * @author zhanglei + * @date 2016年7月27日 + * + */ +public class YarProtocolUtilTest { + + @Before + public void setUp() throws Exception {} + + @After + public void tearDown() throws Exception {} + + @Test + public void testGetYarPath() { + String path = YarProtocolUtil.getYarPath(YarMessageRouterTest.AnnoService.class, null); + assertEquals("/test/anno_path", path); + URL url = new URL("motan", "localhost", 8002, "testpath"); + path = YarProtocolUtil.getYarPath(null, url); + assertEquals("/" + url.getGroup() + "/" + url.getPath(), path); + } + + @Test + public void testConvertYarRequest() throws NoSuchMethodException, SecurityException { + DefaultRequest request = new DefaultRequest(); + request.setRequestId(123); + request.setMethodName("hello"); + request.setArguments(new Object[] {"param1"}); + request.setInterfaceName(YarMessageRouterTest.AnnoService.class.getName()); + request.setParamtersDesc(ReflectUtil.getMethodParamDesc(YarMessageRouterTest.AnnoService.class.getMethod("hello", String.class))); + YarRequest yarRequest = YarProtocolUtil.convert(request, "JSON"); + assertNotNull(yarRequest); + + Request newRequest = YarProtocolUtil.convert(yarRequest, YarMessageRouterTest.AnnoService.class); + assertNotNull(newRequest); + assertEquals(request.toString(), newRequest.toString()); + } + + @Test + // test string cast primitive value + public void testConvertRequest() throws Exception { + String methodName = "testParam"; + Class[] paramClazz = new Class[] {int.class, long.class, boolean.class, float.class, double.class}; + Method method = MethodTestService.class.getDeclaredMethod(methodName, paramClazz); + final String result = "succ"; + MethodTestService service = new MethodTestService() { + @Override + public String testParam(int intParam, long longParam, boolean booleanParam, float floatParam, double doubleParam) { + return result; + } + }; + + // string + Object[] params = new Object[] {"234", "567", "true", "789.12", "678.12"}; + verifyMethodParam(MethodTestService.class, service, method, params, result); + + // number + params = new Object[] {234l, 567, false, 789.12d, 678.12f}; + verifyMethodParam(MethodTestService.class, service, method, params, result); + } + + + private void verifyMethodParam(Class interfaceClazz, T service, Method method, Object[] params, Object expectResult) + throws Exception { + YarRequest yarRequest = new YarRequest(); + yarRequest.setId(123); + yarRequest.setMethodName(method.getName()); + yarRequest.setPackagerName("JSON"); + yarRequest.setParameters(params); + + Request request = YarProtocolUtil.convert(yarRequest, interfaceClazz); + assertNotNull(request); + assertEquals(method.getName(), request.getMethodName()); + Object[] requestParams = request.getArguments(); + assertEquals(params.length, requestParams.length); + Object result = method.invoke(service, requestParams); + assertEquals(expectResult, result); + } + + @Test + public void testConvertYarResponse() { + DefaultResponse response = new DefaultResponse(); + response.setRequestId(456); + response.setValue("stringValue"); + + YarResponse yarResponse = YarProtocolUtil.convert(response, "JSON"); + assertNotNull(yarResponse); + Response newResponse = YarProtocolUtil.convert(yarResponse); + assertEquals(response.getRequestId(), newResponse.getRequestId()); + assertEquals(response.getValue(), newResponse.getValue()); + + + response.setException(new RuntimeException("test exception")); + + yarResponse = YarProtocolUtil.convert(response, "JSON"); + assertNotNull(yarResponse); + newResponse = YarProtocolUtil.convert(yarResponse); + assertEquals(response.getRequestId(), newResponse.getRequestId()); + // yarresponse的异常会转为motan业务异常 + assertEquals(new MotanBizException(response.getException().getMessage()).getMessage(), newResponse.getException().getMessage()); + + } + + @Test + public void testBuildDefaultErrorResponse() { + String errMsg = "test err"; + String packagerName = "MSGPACK"; + YarResponse response = YarProtocolUtil.buildDefaultErrorResponse(errMsg, packagerName); + assertNotNull(response); + assertEquals(errMsg, response.getError()); + assertEquals(packagerName, response.getPackagerName()); + } + + interface MethodTestService { + String testParam(int intParam, long longParam, boolean booleanParam, float floatParam, double doubleParam); + } + +} diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java new file mode 100644 index 000000000..2113b4c63 --- /dev/null +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.protocol.yar; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.weibo.api.motan.rpc.DefaultProvider; +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.transport.MessageHandler; +import com.weibo.api.motan.transport.ProviderMessageRouter; + +/** + * + * @Description YarRpcProtocolTest + * @author zhanglei + * @date 2016年7月27日 + * + */ +public class YarRpcProtocolTest { + + @Before + public void setUp() throws Exception {} + + @After + public void tearDown() throws Exception {} + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Test + public void testInitRequestRouter() { + YarRpcProtocol protocol = new YarRpcProtocol(); + URL url = new URL("motan", "localhost", 8002, "urlpath"); + Provider provider = new DefaultProvider(null, url, MessageHandler.class); + ProviderMessageRouter router = protocol.initRequestRouter(url, provider); + assertNotNull(router); + + URL url2 = new URL("motan", "localhost", 8003, "urlpath2"); + Provider provider2 = new DefaultProvider(null, url2, MessageHandler.class); + ProviderMessageRouter router2 = protocol.initRequestRouter(url2, provider2); + assertNotNull(router2); + assertFalse(router2.equals(router)); + + URL url3 = new URL("motan", "localhost", 8002, "urlpath3"); + Provider provider3 = new DefaultProvider(null, url3, MessageHandler.class); + ProviderMessageRouter router3 = protocol.initRequestRouter(url3, provider3); + assertNotNull(router3); + assertTrue(router3.equals(router)); + + try { + protocol.initRequestRouter(url, provider); + assertTrue(false); + } catch (Exception e) { + assertTrue(e.getMessage().contains("duplicate yar provider")); + } + } + +} diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java new file mode 100644 index 000000000..ed8b2474d --- /dev/null +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java @@ -0,0 +1,152 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.transport.netty4.http; + +import static org.junit.Assert.*; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.DefaultHttpHeaders; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +import org.jmock.Expectations; +import org.jmock.api.Invocation; +import org.jmock.integration.junit4.JUnit4Mockery; +import org.jmock.lib.action.CustomAction; +import org.jmock.lib.legacy.ClassImposteriser; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.weibo.api.motan.common.MotanConstants; +import com.weibo.api.motan.transport.Channel; +import com.weibo.api.motan.transport.MessageHandler; +import com.weibo.api.motan.util.MotanSwitcherUtil; + +/** + * + * @Description NettyHttpRequestHandlerTest + * @author zhanglei + * @date 2016年7月27日 + * + */ +public class NettyHttpRequestHandlerTest { + public static JUnit4Mockery mockery = null; + + @Before + public void setUp() throws Exception { + mockery = new JUnit4Mockery() { + { + setImposteriser(ClassImposteriser.INSTANCE); + } + }; + } + + @After + public void tearDown() throws Exception {} + + @Test + public void testChannelRead0() throws Exception { + final MessageHandler messageHandler = mockery.mock(MessageHandler.class); + final ChannelHandlerContext ctx = mockery.mock(ChannelHandlerContext.class); + final FullHttpResponse response = mockery.mock(FullHttpResponse.class); + mockery.checking(new Expectations() { + { + allowing(ctx).write(with(any(FullHttpResponse.class))); + will(new CustomAction("verify") { + @Override + public Object invoke(Invocation invocation) throws Throwable { + FullHttpResponse actualResponse = (FullHttpResponse) invocation.getParameter(0); + assertNotNull(actualResponse); + assertEquals(response, actualResponse); + return null; + } + + }); + allowing(ctx).flush(); + will(returnValue(null)); + allowing(ctx).close(); + will(returnValue(null)); + + atLeast(1).of(messageHandler).handle(with(any(Channel.class)), with(anything())); + will(returnValue(response)); + allowing(response).headers(); + will(returnValue(new DefaultHttpHeaders())); + } + }); + FullHttpRequest httpRequest = buildHttpRequest("anyPath"); + NettyHttpRequestHandler handler = new NettyHttpRequestHandler(null, messageHandler); + handler.channelRead0(ctx, httpRequest); + } + + @Test + public void testServerStatus() throws Exception { + final MessageHandler messageHandler = mockery.mock(MessageHandler.class); + final ChannelHandlerContext ctx = mockery.mock(ChannelHandlerContext.class); + mockery.checking(new Expectations() { + { + allowing(ctx).write(with(any(FullHttpResponse.class))); + will(new CustomAction("verify") { + @Override + public Object invoke(Invocation invocation) throws Throwable { + verifyStatus((FullHttpResponse) invocation.getParameter(0)); + return null; + } + + }); + allowing(ctx).flush(); + will(returnValue(null)); + allowing(ctx).close(); + will(returnValue(null)); + + allowing(messageHandler).handle(with(any(Channel.class)), with(anything())); + will(returnValue(null)); + } + }); + + FullHttpRequest httpRequest = buildHttpRequest(NettyHttpRequestHandler.ROOT_PATH); + NettyHttpRequestHandler handler = new NettyHttpRequestHandler(null, messageHandler); + + // 关闭心跳开关 + MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false); + handler.channelRead0(ctx, httpRequest); + + // 打开心跳开关 + MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true); + handler.channelRead0(ctx, httpRequest); + + } + + + private void verifyStatus(FullHttpResponse response) { + if (MotanSwitcherUtil.isOpen(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER)) { + assertEquals(HttpResponseStatus.OK, response.getStatus()); + } else { + assertEquals(HttpResponseStatus.SERVICE_UNAVAILABLE, response.getStatus()); + } + } + + private FullHttpRequest buildHttpRequest(String requestPath) throws Exception { + PooledByteBufAllocator allocator = new PooledByteBufAllocator(); + ByteBuf buf = allocator.buffer(0); + FullHttpRequest httpReqeust = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, requestPath, buf); + return httpReqeust; + } + +} diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java new file mode 100644 index 000000000..793878d94 --- /dev/null +++ b/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java @@ -0,0 +1,156 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed 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 com.weibo.api.motan.transport.netty4.yar; + +import static org.junit.Assert.*; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.weibo.api.motan.protocol.yar.AttachmentRequest; +import com.weibo.api.motan.protocol.yar.YarMessageRouter; +import com.weibo.api.motan.protocol.yar.YarProtocolUtil; +import com.weibo.api.motan.rpc.DefaultResponse; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.rpc.URL; +import com.weibo.api.motan.transport.Channel; +import com.weibo.api.motan.transport.MessageHandler; +import com.weibo.api.motan.transport.TransportException; +import com.weibo.api.motan.transport.netty4.http.Netty4HttpServer; +import com.weibo.yar.YarProtocol; +import com.weibo.yar.YarRequest; +import com.weibo.yar.YarResponse; + +/** + * + * @Description YarMessageHandlerWarpperTest + * @author zhanglei + * @date 2016年7月27日 + * + */ +public class YarMessageHandlerWarpperTest { + public String uri = "/testpath?param1=a¶m2=b¶m3=c"; + + @Before + public void setUp() throws Exception {} + + @After + public void tearDown() throws Exception {} + + @Test + public void testHandle() throws Exception { + YarRequest yarRequest = new YarRequest(123, "JSON", "testmethod", new Object[] {"params", 456}); + final YarResponse yarResponse = YarProtocolUtil.buildDefaultErrorResponse("test err", "JSON"); + YarMessageHandlerWarpper handler = new YarMessageHandlerWarpper(new YarMessageRouter() { + + @Override + public Object handle(Channel channel, Object message) { + AttachmentRequest request = (AttachmentRequest) message; + verifyAttachments(request.getAttachments()); + return yarResponse; + } + }); + FullHttpResponse httpResponse = (FullHttpResponse) handler.handle(new MockChannel(), buildHttpRequest(yarRequest, uri)); + + assertNotNull(httpResponse); + assertNotNull(httpResponse.content()); + YarResponse retYarResponse = getYarResponse(httpResponse); + assertNotNull(retYarResponse); + assertEquals(yarResponse, retYarResponse); + } + + @Test + public void testAbnormal() throws Exception { + final String errmsg = "rpc process error"; + YarMessageHandlerWarpper handler = new YarMessageHandlerWarpper(new YarMessageRouter() { + + @Override + public Object handle(Channel channel, Object message) { + throw new RuntimeException(errmsg); + } + }); + // yar协议无法解析 + FullHttpResponse httpResponse = (FullHttpResponse) handler.handle(new MockChannel(), buildHttpRequest(null, uri)); + assertNotNull(httpResponse); + assertEquals(HttpResponseStatus.OK, httpResponse.getStatus()); + YarResponse retYarResponse = getYarResponse(httpResponse); + assertNotNull(retYarResponse); + assertNotNull(retYarResponse.getError()); + + // yar协议可以正常解析,但后续处理异常 + YarRequest yarRequest = new YarRequest(123, "JSON", "testmethod", new Object[] {"params", 456}); + httpResponse = (FullHttpResponse) handler.handle(new MockChannel(), buildHttpRequest(yarRequest, uri)); + assertNotNull(httpResponse); + assertEquals(HttpResponseStatus.OK, httpResponse.getStatus()); + retYarResponse = getYarResponse(httpResponse); + assertNotNull(retYarResponse); + assertEquals(errmsg, retYarResponse.getError()); + } + + private void verifyAttachments(Map attachments) { + String[] params = uri.substring(uri.indexOf("?") + 1).split("&"); + for (String param : params) { + String k = param.split("=")[0]; + String v = param.split("=")[1]; + assertTrue(attachments.containsKey(k)); + assertEquals(v, attachments.get(k)); + } + } + + private YarResponse getYarResponse(FullHttpResponse httpResponse) throws Exception { + ByteBuf buf = httpResponse.content(); + final byte[] contentBytes = new byte[buf.readableBytes()]; + buf.getBytes(0, contentBytes); + YarResponse yarResponse = YarProtocol.buildResponse(contentBytes); + return yarResponse; + } + + private FullHttpRequest buildHttpRequest(YarRequest yarRequest, String requestPath) throws Exception { + PooledByteBufAllocator allocator = new PooledByteBufAllocator(); + ByteBuf buf = allocator.buffer(2048, 1024 * 1024); + if (yarRequest != null) { + buf.writeBytes(YarProtocol.toProtocolBytes(yarRequest)); + } + FullHttpRequest httpReqeust = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, requestPath, buf); + return httpReqeust; + } + + class MockChannel extends Netty4HttpServer { + public MockChannel() { + super(null, null); + } + + public MockChannel(URL url, MessageHandler messageHandler) { + super(url, messageHandler); + } + + @Override + public Response request(Request request) throws TransportException { + return new DefaultResponse(); + } + } + +} From 251580855402274ca7e719c3c7c0a1e6a277d0ed Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 2 Aug 2016 22:26:58 +0800 Subject: [PATCH 09/10] modify package name --- .../motan-protocol-yar/pom.xml | 0 .../weibo/api/motan/protocol/yar/AttachmentRequest.java | 2 +- .../java/com/weibo/api/motan/protocol/yar/YarExporter.java | 2 +- .../com/weibo/api/motan/protocol/yar/YarMessageRouter.java | 2 +- .../com/weibo/api/motan/protocol/yar/YarProtocolUtil.java | 2 +- .../java/com/weibo/api/motan/protocol/yar/YarReferer.java | 0 .../com/weibo/api/motan/protocol/yar/YarRpcProtocol.java | 7 ++++--- .../weibo/api/motan/protocol/yar/annotation/YarConfig.java | 6 +++--- .../api/motan/transport/netty4/http/Netty4HttpServer.java | 4 ++-- .../transport/netty4/http/NettyHttpRequestHandler.java | 2 +- .../motan/transport/netty4/http/NoHeartbeatFactory.java | 2 +- .../transport/netty4/yar/Netty4YarEndpointFactory.java | 7 ++++--- .../transport/netty4/yar/YarMessageHandlerWarpper.java | 2 +- .../META-INF/services/com.weibo.api.motan.rpc.Protocol | 0 .../services/com.weibo.api.motan.transport.EndpointFactory | 0 .../com.weibo.api.motan.transport.HeartbeatFactory | 0 .../weibo/api/motan/protocol/yar/YarMessageRouterTest.java | 0 .../weibo/api/motan/protocol/yar/YarProtocolUtilTest.java | 0 .../weibo/api/motan/protocol/yar/YarRpcProtocolTest.java | 0 .../transport/netty4/http/NettyHttpRequestHandlerTest.java | 0 .../transport/netty4/yar/YarMessageHandlerWarpperTest.java | 0 .../{protocl-extension => protocol-extension}/pom.xml | 0 22 files changed, 20 insertions(+), 18 deletions(-) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/pom.xml (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java (98%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java (99%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java (99%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java (99%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java (94%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java (92%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java (99%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java (99%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java (98%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java (89%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java (99%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarMessageRouterTest.java (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java (100%) rename motan-extension/{protocl-extension => protocol-extension}/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java (100%) rename motan-extension/{protocl-extension => protocol-extension}/pom.xml (100%) diff --git a/motan-extension/protocl-extension/motan-protocol-yar/pom.xml b/motan-extension/protocol-extension/motan-protocol-yar/pom.xml similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/pom.xml rename to motan-extension/protocol-extension/motan-protocol-yar/pom.xml diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java similarity index 98% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java index f50528008..6105ed9bc 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/AttachmentRequest.java @@ -22,7 +22,7 @@ * @Description YarRequest with attachments. rpc attachments such as auth,application can pass with * this class. * @author zhanglei - * @date 2016年7月26日 + * @date 2016-7-26 * */ public class AttachmentRequest extends YarRequest { diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java similarity index 99% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java index 83022ff88..aaa06403f 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarExporter.java @@ -31,7 +31,7 @@ * * @Description YarExporter * @author zhanglei - * @date 2016年5月31日 + * @date 2016-5-31 * */ public class YarExporter extends AbstractExporter { diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java similarity index 99% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java index f1e01e345..b661203e8 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarMessageRouter.java @@ -28,7 +28,7 @@ * * @Description yar message router * @author zhanglei - * @date 2016年6月8日 + * @date 2016-6-8 * */ public class YarMessageRouter extends ProviderProtectedMessageRouter { diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java similarity index 99% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java index d21be794d..c9f07e4d6 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarProtocolUtil.java @@ -33,7 +33,7 @@ * * @Description yar protocol util. * @author zhanglei - * @date 2016年6月8日 + * @date 2016-6-8 * */ public class YarProtocolUtil { diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarReferer.java diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java similarity index 94% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java index 74e8e2d4f..43a28e8e4 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/YarRpcProtocol.java @@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.exception.MotanFrameworkException; import com.weibo.api.motan.protocol.AbstractProtocol; import com.weibo.api.motan.rpc.Exporter; import com.weibo.api.motan.rpc.Provider; @@ -29,7 +30,7 @@ * * @Description yar rpc protocol * @author zhanglei - * @date 2016年5月25日 + * @date 2016-5-25 * */ @SpiMeta(name = "yar") @@ -44,8 +45,8 @@ protected Exporter createExporter(Provider provider, URL url) { @Override protected Referer createReferer(Class clz, URL url, URL serviceUrl) { - // TODO Auto-generated method stub - return null; + //TODO + throw new MotanFrameworkException("not yet implemented!"); } public ProviderMessageRouter initRequestRouter(URL url, Provider provider) { diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java similarity index 92% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java index df1cf24d4..b5730404b 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/protocol/yar/annotation/YarConfig.java @@ -22,16 +22,16 @@ /** * - * @Description yar rpc 配置 + * @Description yar rpc config * @author zhanglei - * @date 2016年6月7日 + * @date 2016-6-7 * */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface YarConfig { /** - * yar rpc 的request path + * yar rpc request path * @return path */ String path() default ""; diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java similarity index 99% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java index 519e6bd6e..2b7aa961a 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/Netty4HttpServer.java @@ -49,10 +49,10 @@ * * @Description netty 4 http server. * @author zhanglei - * @date 2016年5月31日 + * @date 2016-5-31 * */ -// TODO 后续移到transport netty4 模块 +// TODO move to transport netty4 module public class Netty4HttpServer extends AbstractServer implements StatisticCallback { private MessageHandler messageHandler; private URL url; diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java similarity index 99% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java index 46029d915..2b003a5c7 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandler.java @@ -37,7 +37,7 @@ * * @Description http request handler for netty4 * @author zhanglei - * @date 2016年5月31日 + * @date 2016-5-31 * */ diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java similarity index 98% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java index c17bcca78..94fcc2861 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/http/NoHeartbeatFactory.java @@ -22,7 +22,7 @@ * * @Description no heartbeatFactory * @author zhanglei - * @date 2016年6月8日 + * @date 2016-6-8 * */ @SpiMeta(name = "noHeartbeat") diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java similarity index 89% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java index 7633676f8..4ab54aefd 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/Netty4YarEndpointFactory.java @@ -14,6 +14,7 @@ package com.weibo.api.motan.transport.netty4.yar; import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.exception.MotanFrameworkException; import com.weibo.api.motan.rpc.URL; import com.weibo.api.motan.transport.Client; import com.weibo.api.motan.transport.MessageHandler; @@ -25,7 +26,7 @@ * * @Description yar endpoint factory use netty4 * @author zhanglei - * @date 2016年5月31日 + * @date 2016-5-31 * */ @SpiMeta(name = "netty4yar") @@ -38,8 +39,8 @@ protected Server innerCreateServer(URL url, MessageHandler messageHandler) { @Override protected Client innerCreateClient(URL url) { - // TODO Auto-generated method stub - return null; + // TODO + throw new MotanFrameworkException("not yet implemented!"); } } diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java similarity index 99% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java index e8653d175..5efbd4413 100644 --- a/motan-extension/protocl-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java +++ b/motan-extension/protocol-extension/motan-protocol-yar/src/main/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpper.java @@ -42,7 +42,7 @@ * * @Description wrapper to process yar message * @author zhanglei - * @date 2016年5月31日 + * @date 2016-5-31 * */ public class YarMessageHandlerWarpper implements MessageHandler { diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol b/motan-extension/protocol-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.rpc.Protocol diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory b/motan-extension/protocol-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.EndpointFactory diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory b/motan-extension/protocol-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory rename to motan-extension/protocol-extension/motan-protocol-yar/src/main/resources/META-INF/services/com.weibo.api.motan.transport.HeartbeatFactory diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarMessageRouterTest.java b/motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarMessageRouterTest.java similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarMessageRouterTest.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarMessageRouterTest.java diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java b/motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarProtocolUtilTest.java diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java b/motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/protocol/yar/YarRpcProtocolTest.java diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java b/motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/http/NettyHttpRequestHandlerTest.java diff --git a/motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java b/motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java similarity index 100% rename from motan-extension/protocl-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java rename to motan-extension/protocol-extension/motan-protocol-yar/src/test/java/com/weibo/api/motan/transport/netty4/yar/YarMessageHandlerWarpperTest.java diff --git a/motan-extension/protocl-extension/pom.xml b/motan-extension/protocol-extension/pom.xml similarity index 100% rename from motan-extension/protocl-extension/pom.xml rename to motan-extension/protocol-extension/pom.xml From 3bb0db303bd11fa124516f6751db34c06de59683 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 2 Aug 2016 22:31:33 +0800 Subject: [PATCH 10/10] update pom --- motan-extension/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motan-extension/pom.xml b/motan-extension/pom.xml index d967162af..dafd23ca6 100644 --- a/motan-extension/pom.xml +++ b/motan-extension/pom.xml @@ -24,6 +24,6 @@ pom serialization-extension - protocl-extension + protocol-extension \ No newline at end of file