Java tutorial
/* * Copyright 2002-2014 the original author or authors. * * 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.baidu.jprotobuf.pbrpc.transport.handler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import java.lang.reflect.InvocationTargetException; import java.util.logging.Level; import java.util.logging.Logger; import com.baidu.jprotobuf.pbrpc.ErrorDataException; import com.baidu.jprotobuf.pbrpc.RpcHandler; import com.baidu.jprotobuf.pbrpc.data.ProtocolConstant; import com.baidu.jprotobuf.pbrpc.data.RpcDataPackage; import com.baidu.jprotobuf.pbrpc.data.RpcMeta; import com.baidu.jprotobuf.pbrpc.server.RpcData; import com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry; /** * RPC service handler on request data arrived. * * @author xiemalin * @since 1.0 */ public class RpcServiceHandler extends SimpleChannelInboundHandler<RpcDataPackage> { /** * log this class */ private static final Logger LOG = Logger.getLogger(RpcServiceHandler.class.getName()); /** * {@link RpcServiceRegistry} */ private final RpcServiceRegistry rpcServiceRegistry; /** * @param rpcServiceRegistry */ public RpcServiceHandler(RpcServiceRegistry rpcServiceRegistry) { this.rpcServiceRegistry = rpcServiceRegistry; } @Override protected void channelRead0(ChannelHandlerContext ctx, RpcDataPackage dataPackage) throws Exception { long time = System.currentTimeMillis(); RpcMeta rpcMeta = dataPackage.getRpcMeta(); String serviceName = rpcMeta.getRequest().getSerivceName(); String methodName = rpcMeta.getRequest().getMethodName(); try { RpcHandler handler = rpcServiceRegistry.lookupService(serviceName, methodName); if (handler == null) { dataPackage.errorCode(ErrorCodes.ST_SERVICE_NOTFOUND); dataPackage.errorText(ErrorCodes.MSG_SERVICE_NOTFOUND); } else { byte[] data = dataPackage.getData(); RpcData request = new RpcData(); request.setLogId(dataPackage.getRpcMeta().getRequest().getLogId()); request.setData(data); request.setAttachment(dataPackage.getAttachment()); if (dataPackage.getRpcMeta() != null) { request.setAuthenticationData(dataPackage.getRpcMeta().getAuthenticationData()); } request.setExtraParams(dataPackage.getRpcMeta().getRequest().getExtraParam()); try { RpcData response = handler.doHandle(request); dataPackage.data(response.getData()); dataPackage.attachment(response.getAttachment()); dataPackage.authenticationData(response.getAuthenticationData()); dataPackage.errorCode(ErrorCodes.ST_SUCCESS); dataPackage.errorText(null); } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException == null) { targetException = e; } LOG.log(Level.SEVERE, targetException.getMessage(), targetException); // catch business exception dataPackage.errorCode(ErrorCodes.ST_ERROR); dataPackage.errorText(targetException.getMessage()); } catch (Exception e) { LOG.log(Level.SEVERE, e.getMessage(), e.getCause()); // catch business exception dataPackage.errorCode(ErrorCodes.ST_ERROR); dataPackage.errorText(e.getMessage()); } } // We do not need to write a ChannelBuffer here. // We know the encoder inserted at TelnetPipelineFactory will do the // conversion. ctx.writeAndFlush(dataPackage); } catch (Exception t) { ErrorDataException exception = new ErrorDataException(t.getMessage(), t); exception.setErrorCode(ErrorCodes.ST_ERROR); exception.setRpcDataPackage(dataPackage); throw exception; } finally { LOG.info("RPC server invoke method '" + methodName + "' time took:" + (System.currentTimeMillis() - time) + " ms"); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { LOG.log(Level.SEVERE, cause.getCause().getMessage(), cause.getCause()); RpcDataPackage data = null; if (cause instanceof ErrorDataException) { ErrorDataException error = (ErrorDataException) cause; RpcDataPackage dataPackage = error.getRpcDataPackage(); if (dataPackage != null) { int errorCode = ErrorCodes.ST_ERROR; if (error.getErrorCode() > 0) { errorCode = error.getErrorCode(); } data = dataPackage.getErrorResponseRpcDataPackage(errorCode, cause.getCause().getMessage()); } } if (data == null) { data = new RpcDataPackage(); data = data.magicCode(ProtocolConstant.MAGIC_CODE).getErrorResponseRpcDataPackage(ErrorCodes.ST_ERROR, cause.getCause().getMessage()); } ctx.fireChannelRead(data); } }