| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.oncrpc; |
| |
| import java.util.Arrays; |
| |
| import org.apache.hadoop.oncrpc.RpcAcceptedReply.AcceptState; |
| import org.jboss.netty.buffer.ChannelBuffer; |
| import org.jboss.netty.channel.ChannelHandlerContext; |
| import org.jboss.netty.channel.MessageEvent; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * A simple client that registers an RPC program with portmap. |
| */ |
| public class RegistrationClient extends SimpleTcpClient { |
| public static final Logger LOG = |
| LoggerFactory.getLogger(RegistrationClient.class); |
| |
| public RegistrationClient(String host, int port, XDR request) { |
| super(host, port, request); |
| } |
| |
| /** |
| * Handler to handle response from the server. |
| */ |
| static class RegistrationClientHandler extends SimpleTcpClientHandler { |
| public RegistrationClientHandler(XDR request) { |
| super(request); |
| } |
| |
| private boolean validMessageLength(int len) { |
| // 28 bytes is the minimal success response size (portmapV2) |
| if (len < 28) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Portmap mapping registration failed," |
| + " the response size is less than 28 bytes:" + len); |
| } |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { |
| ChannelBuffer buf = (ChannelBuffer) e.getMessage(); // Read reply |
| if (!validMessageLength(buf.readableBytes())) { |
| e.getChannel().close(); |
| return; |
| } |
| |
| // handling fragment header for TCP, 4 bytes. |
| byte[] fragmentHeader = Arrays.copyOfRange(buf.array(), 0, 4); |
| int fragmentSize = XDR.fragmentSize(fragmentHeader); |
| boolean isLast = XDR.isLastFragment(fragmentHeader); |
| assert (fragmentSize == 28 && isLast == true); |
| |
| XDR xdr = new XDR(); |
| xdr.writeFixedOpaque(Arrays.copyOfRange(buf.array(), 4, |
| buf.readableBytes())); |
| |
| RpcReply reply = RpcReply.read(xdr); |
| if (reply.getState() == RpcReply.ReplyState.MSG_ACCEPTED) { |
| RpcAcceptedReply acceptedReply = (RpcAcceptedReply) reply; |
| handle(acceptedReply, xdr); |
| } else { |
| RpcDeniedReply deniedReply = (RpcDeniedReply) reply; |
| handle(deniedReply); |
| } |
| e.getChannel().close(); // shutdown now that request is complete |
| } |
| |
| private void handle(RpcDeniedReply deniedReply) { |
| LOG.warn("Portmap mapping registration request was denied , " + |
| deniedReply); |
| } |
| |
| private void handle(RpcAcceptedReply acceptedReply, XDR xdr) { |
| AcceptState acceptState = acceptedReply.getAcceptState(); |
| assert (acceptState == AcceptState.SUCCESS); |
| boolean answer = xdr.readBoolean(); |
| if (answer != true) { |
| LOG.warn("Portmap mapping registration failed, accept state:" |
| + acceptState); |
| } |
| LOG.info("Portmap mapping registration succeeded"); |
| } |
| } |
| } |