PageRenderTime 28ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/avro-1.6.2/lang/java/ipc/src/main/java/org/apache/avro/ipc/NettyServer.java

#
Java | 177 lines | 124 code | 21 blank | 32 comment | 5 complexity | de6766eb2f9ad34ac29c06a3818e5d6b MD5 | raw file
Possible License(s): Apache-2.0, JSON
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.avro.ipc;
  19. import java.io.IOException;
  20. import java.net.InetSocketAddress;
  21. import java.nio.ByteBuffer;
  22. import java.util.List;
  23. import java.util.concurrent.CountDownLatch;
  24. import java.util.concurrent.Executors;
  25. import org.apache.avro.ipc.NettyTransportCodec.NettyDataPack;
  26. import org.apache.avro.ipc.NettyTransportCodec.NettyFrameDecoder;
  27. import org.apache.avro.ipc.NettyTransportCodec.NettyFrameEncoder;
  28. import org.jboss.netty.bootstrap.ServerBootstrap;
  29. import org.jboss.netty.channel.Channel;
  30. import org.jboss.netty.channel.ChannelEvent;
  31. import org.jboss.netty.channel.ChannelFactory;
  32. import org.jboss.netty.channel.ChannelHandlerContext;
  33. import org.jboss.netty.channel.ChannelPipeline;
  34. import org.jboss.netty.channel.ChannelPipelineFactory;
  35. import org.jboss.netty.channel.ChannelStateEvent;
  36. import org.jboss.netty.channel.Channels;
  37. import org.jboss.netty.channel.ExceptionEvent;
  38. import org.jboss.netty.channel.MessageEvent;
  39. import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
  40. import org.jboss.netty.channel.group.ChannelGroup;
  41. import org.jboss.netty.channel.group.ChannelGroupFuture;
  42. import org.jboss.netty.channel.group.DefaultChannelGroup;
  43. import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
  44. import org.jboss.netty.handler.execution.ExecutionHandler;
  45. import org.slf4j.Logger;
  46. import org.slf4j.LoggerFactory;
  47. /**
  48. * A Netty-based RPC {@link Server} implementation.
  49. */
  50. public class NettyServer implements Server {
  51. private static final Logger LOG = LoggerFactory.getLogger(NettyServer.class
  52. .getName());
  53. private final Responder responder;
  54. private final Channel serverChannel;
  55. private final ChannelGroup allChannels = new DefaultChannelGroup(
  56. "avro-netty-server");
  57. private final ChannelFactory channelFactory;
  58. private final CountDownLatch closed = new CountDownLatch(1);
  59. private final ExecutionHandler executionHandler;
  60. public NettyServer(Responder responder, InetSocketAddress addr) {
  61. this(responder, addr, new NioServerSocketChannelFactory
  62. (Executors .newCachedThreadPool(), Executors.newCachedThreadPool()));
  63. }
  64. public NettyServer(Responder responder, InetSocketAddress addr,
  65. ChannelFactory channelFactory) {
  66. this(responder, addr, channelFactory, null);
  67. }
  68. /**
  69. *
  70. * @param executionHandler if not null, will be inserted into the Netty
  71. * pipeline. Use this when your responder does
  72. * long, non-cpu bound processing (see Netty's
  73. * ExecutionHandler javadoc).
  74. */
  75. public NettyServer(Responder responder, InetSocketAddress addr,
  76. ChannelFactory channelFactory, final ExecutionHandler executionHandler) {
  77. this.responder = responder;
  78. this.channelFactory = channelFactory;
  79. this.executionHandler = executionHandler;
  80. ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);
  81. bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
  82. @Override
  83. public ChannelPipeline getPipeline() throws Exception {
  84. ChannelPipeline p = Channels.pipeline();
  85. p.addLast("frameDecoder", new NettyFrameDecoder());
  86. p.addLast("frameEncoder", new NettyFrameEncoder());
  87. if (executionHandler != null) {
  88. p.addLast("executionHandler", executionHandler);
  89. }
  90. p.addLast("handler", new NettyServerAvroHandler());
  91. return p;
  92. }
  93. });
  94. serverChannel = bootstrap.bind(addr);
  95. allChannels.add(serverChannel);
  96. }
  97. @Override
  98. public void start() {
  99. // No-op.
  100. }
  101. @Override
  102. public void close() {
  103. ChannelGroupFuture future = allChannels.close();
  104. future.awaitUninterruptibly();
  105. channelFactory.releaseExternalResources();
  106. closed.countDown();
  107. }
  108. @Override
  109. public int getPort() {
  110. return ((InetSocketAddress) serverChannel.getLocalAddress()).getPort();
  111. }
  112. @Override
  113. public void join() throws InterruptedException {
  114. closed.await();
  115. }
  116. /**
  117. * Avro server handler for the Netty transport
  118. */
  119. class NettyServerAvroHandler extends SimpleChannelUpstreamHandler {
  120. private NettyTransceiver connectionMetadata = new NettyTransceiver();
  121. @Override
  122. public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
  123. throws Exception {
  124. if (e instanceof ChannelStateEvent) {
  125. LOG.info(e.toString());
  126. }
  127. super.handleUpstream(ctx, e);
  128. }
  129. @Override
  130. public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
  131. throws Exception {
  132. allChannels.add(e.getChannel());
  133. super.channelOpen(ctx, e);
  134. }
  135. @Override
  136. public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
  137. try {
  138. NettyDataPack dataPack = (NettyDataPack) e.getMessage();
  139. List<ByteBuffer> req = dataPack.getDatas();
  140. List<ByteBuffer> res = responder.respond(req, connectionMetadata);
  141. // response will be null for oneway messages.
  142. if(res != null) {
  143. dataPack.setDatas(res);
  144. e.getChannel().write(dataPack);
  145. }
  146. } catch (IOException ex) {
  147. LOG.warn("unexpect error");
  148. }
  149. }
  150. @Override
  151. public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
  152. LOG.warn("Unexpected exception from downstream.", e.getCause());
  153. e.getChannel().close();
  154. }
  155. }
  156. }