예제 #1
0
 protected Object decodeBody(Channel channel, InputStream is, byte[] header) throws IOException {
   byte flag = header[2], proto = (byte) (flag & SERIALIZATION_MASK);
   Serialization s = CodecSupport.getSerialization(channel.getUrl(), proto);
   ObjectInput in = s.deserialize(channel.getUrl(), is);
   // get request id.
   long id = Bytes.bytes2long(header, 4);
   if ((flag & FLAG_REQUEST) == 0) {
     // decode response.
     Response res = new Response(id);
     if ((flag & FLAG_EVENT) != 0) {
       res.setEvent(Response.HEARTBEAT_EVENT);
     }
     // get status.
     byte status = header[3];
     res.setStatus(status);
     if (status == Response.OK) {
       try {
         Object data;
         if (res.isHeartbeat()) {
           data = decodeHeartbeatData(channel, in);
         } else if (res.isEvent()) {
           data = decodeEventData(channel, in);
         } else {
           data = decodeResponseData(channel, in, getRequestData(id));
         }
         res.setResult(data);
       } catch (Throwable t) {
         res.setStatus(Response.CLIENT_ERROR);
         res.setErrorMessage(StringUtils.toString(t));
       }
     } else {
       res.setErrorMessage(in.readUTF());
     }
     return res;
   } else {
     // decode request.
     Request req = new Request(id);
     req.setVersion("2.0.0");
     req.setTwoWay((flag & FLAG_TWOWAY) != 0);
     if ((flag & FLAG_EVENT) != 0) {
       req.setEvent(Request.HEARTBEAT_EVENT);
     }
     try {
       Object data;
       if (req.isHeartbeat()) {
         data = decodeHeartbeatData(channel, in);
       } else if (req.isEvent()) {
         data = decodeEventData(channel, in);
       } else {
         data = decodeRequestData(channel, in);
       }
       req.setData(data);
     } catch (Throwable t) {
       // bad request
       req.setBroken(true);
       req.setData(t);
     }
     return req;
   }
 }
예제 #2
0
  protected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req)
      throws IOException {
    Serialization serialization = getSerialization(channel);
    // header.
    byte[] header = new byte[HEADER_LENGTH];
    // set magic number.
    Bytes.short2bytes(MAGIC, header);

    // set request and serialization flag.
    header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId());

    if (req.isTwoWay()) header[2] |= FLAG_TWOWAY;
    if (req.isEvent()) header[2] |= FLAG_EVENT;

    // set request id.
    Bytes.long2bytes(req.getId(), header, 4);

    // encode request data.
    int savedWriteIndex = buffer.writerIndex();
    buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);
    ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
    ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
    try {
      if (req.isEvent()) {
        encodeEventData(channel, out, req.getData());
      } else {
        encodeRequestData(channel, out, req.getData());
      }
      out.flushBuffer();
    } finally {
      // modified by lishen
      if (out instanceof Cleanable) {
        ((Cleanable) out).cleanup();
      }
    }

    bos.flush();
    bos.close();
    int len = bos.writtenBytes();
    checkPayload(channel, len);
    Bytes.int2bytes(len, header, 12);

    // write
    buffer.writerIndex(savedWriteIndex);
    buffer.writeBytes(header); // write header.
    buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
  }
예제 #3
0
 public String telnet(Channel channel, String message) {
   if (message.length() > 0) {
     if (!extensionLoader.hasExtension(message)) {
       return "No such command " + message;
     }
     TelnetHandler handler = extensionLoader.getExtension(message);
     Help help = handler.getClass().getAnnotation(Help.class);
     StringBuilder buf = new StringBuilder();
     buf.append("Command:\r\n    ");
     buf.append(message + " " + help.parameter().replace("\r\n", " ").replace("\n", " "));
     buf.append("\r\nSummary:\r\n    ");
     buf.append(help.summary().replace("\r\n", " ").replace("\n", " "));
     buf.append("\r\nDetail:\r\n    ");
     buf.append(help.detail().replace("\r\n", "    \r\n").replace("\n", "    \n"));
     return buf.toString();
   } else {
     List<List<String>> table = new ArrayList<List<String>>();
     List<TelnetHandler> handlers =
         extensionLoader.getActivateExtension(channel.getUrl(), "telnet");
     if (handlers != null && handlers.size() > 0) {
       for (TelnetHandler handler : handlers) {
         Help help = handler.getClass().getAnnotation(Help.class);
         List<String> row = new ArrayList<String>();
         String parameter =
             " "
                 + extensionLoader.getExtensionName(handler)
                 + " "
                 + (help != null ? help.parameter().replace("\r\n", " ").replace("\n", " ") : "");
         row.add(parameter.length() > 50 ? parameter.substring(0, 50) + "..." : parameter);
         String summary =
             help != null ? help.summary().replace("\r\n", " ").replace("\n", " ") : "";
         row.add(summary.length() > 50 ? summary.substring(0, 50) + "..." : summary);
         table.add(row);
       }
     }
     return "Please input \"help [command]\" show detail.\r\n" + TelnetUtils.toList(table);
   }
 }
예제 #4
0
  protected void encodeResponse(Channel channel, ChannelBuffer buffer, Response res)
      throws IOException {
    try {
      Serialization serialization = getSerialization(channel);
      // header.
      byte[] header = new byte[HEADER_LENGTH];
      // set magic number.
      Bytes.short2bytes(MAGIC, header);
      // set request and serialization flag.
      header[2] = serialization.getContentTypeId();
      if (res.isHeartbeat()) header[2] |= FLAG_EVENT;
      // set response status.
      byte status = res.getStatus();
      header[3] = status;
      // set request id.
      Bytes.long2bytes(res.getId(), header, 4);

      int savedWriteIndex = buffer.writerIndex();
      buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);
      ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
      ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
      try {
        // encode response data or error message.
        if (status == Response.OK) {
          if (res.isHeartbeat()) {
            encodeHeartbeatData(channel, out, res.getResult());
          } else {
            encodeResponseData(channel, out, res.getResult());
          }
        } else out.writeUTF(res.getErrorMessage());
        out.flushBuffer();
      } finally {
        // modified by lishen
        if (out instanceof Cleanable) {
          ((Cleanable) out).cleanup();
        }
      }

      bos.flush();
      bos.close();

      int len = bos.writtenBytes();
      checkPayload(channel, len);
      Bytes.int2bytes(len, header, 12);
      // write
      buffer.writerIndex(savedWriteIndex);
      buffer.writeBytes(header); // write header.
      buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
    } catch (Throwable t) {
      // 发送失败信息给Consumer,否则Consumer只能等超时了
      if (!res.isEvent() && res.getStatus() != Response.BAD_RESPONSE) {
        try {
          // FIXME 在Codec中打印出错日志?在IoHanndler的caught中统一处理?
          logger.warn(
              "Fail to encode response: "
                  + res
                  + ", send bad_response info instead, cause: "
                  + t.getMessage(),
              t);

          Response r = new Response(res.getId(), res.getVersion());
          r.setStatus(Response.BAD_RESPONSE);
          r.setErrorMessage(
              "Failed to send response: " + res + ", cause: " + StringUtils.toString(t));
          channel.send(r);

          return;
        } catch (RemotingException e) {
          logger.warn(
              "Failed to send bad_response info back: " + res + ", cause: " + e.getMessage(), e);
        }
      }

      // 重新抛出收到的异常
      if (t instanceof IOException) {
        throw (IOException) t;
      } else if (t instanceof RuntimeException) {
        throw (RuntimeException) t;
      } else if (t instanceof Error) {
        throw (Error) t;
      } else {
        throw new RuntimeException(t.getMessage(), t);
      }
    }
  }