예제 #1
0
  /** Perform the Pyro protocol connection handshake with the Pyro daemon. */
  @SuppressWarnings("unchecked")
  protected void _handshake() throws IOException {
    // do connection handshake

    PyroSerializer ser = PyroSerializer.getFor(Config.SERIALIZER);
    Map<String, Object> handshakedata = new HashMap<String, Object>();
    handshakedata.put("handshake", pyroHandshake);
    if (Config.METADATA) handshakedata.put("object", objectid);
    byte[] data = ser.serializeData(handshakedata);
    int flags = Config.METADATA ? Message.FLAGS_META_ON_CONNECT : 0;
    Message msg =
        new Message(
            Message.MSG_CONNECT,
            data,
            ser.getSerializerId(),
            flags,
            sequenceNr,
            annotations(),
            pyroHmacKey);
    IOUtil.send(sock_out, msg.to_bytes());
    if (Config.MSG_TRACE_DIR != null) {
      Message.TraceMessageSend(
          sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
    }

    // process handshake response
    msg =
        Message.recv(
            sock_in, new int[] {Message.MSG_CONNECTOK, Message.MSG_CONNECTFAIL}, pyroHmacKey);
    responseAnnotations(msg.annotations, msg.type);
    Object handshake_response = "?";
    if (msg.data != null) {
      if ((msg.flags & Message.FLAGS_COMPRESSED) != 0) {
        _decompressMessageData(msg);
      }
      handshake_response = ser.deserializeData(msg.data);
    }
    if (msg.type == Message.MSG_CONNECTOK) {
      if ((msg.flags & Message.FLAGS_META_ON_CONNECT) != 0) {
        HashMap<String, Object> response_dict = (HashMap<String, Object>) handshake_response;
        HashMap<String, Object> metadata = (HashMap<String, Object>) response_dict.get("meta");
        _processMetadata(metadata);
        handshake_response = response_dict.get("handshake");
        try {
          validateHandshake(handshake_response);
        } catch (IOException x) {
          close();
          throw x;
        }
      }
    } else if (msg.type == Message.MSG_CONNECTFAIL) {
      close();
      throw new PyroException("connection rejected, reason: " + handshake_response);
    } else {
      close();
      throw new PyroException("connect: invalid msg type " + msg.type + " received");
    }
  }
예제 #2
0
  /** Internal call method to actually perform the Pyro method call and process the result. */
  private Object internal_call(
      String method,
      String actual_objectId,
      int flags,
      boolean checkMethodName,
      Object... parameters)
      throws PickleException, PyroException, IOException {
    if (actual_objectId == null) actual_objectId = this.objectid;
    synchronized (this) {
      connect();
      sequenceNr = (sequenceNr + 1) & 0xffff; // stay within an unsigned short 0-65535
    }
    if (pyroAttrs.contains(method)) {
      throw new PyroException("cannot call an attribute");
    }
    if (pyroOneway.contains(method)) {
      flags |= Message.FLAGS_ONEWAY;
    }
    if (checkMethodName && Config.METADATA && !pyroMethods.contains(method)) {
      throw new PyroException(
          String.format(
              "remote object '%s' has no exposed attribute or method '%s'",
              actual_objectId, method));
    }
    if (parameters == null) parameters = new Object[] {};
    PyroSerializer ser = PyroSerializer.getFor(Config.SERIALIZER);
    byte[] pickle =
        ser.serializeCall(
            actual_objectId, method, parameters, Collections.<String, Object>emptyMap());
    Message msg =
        new Message(
            Message.MSG_INVOKE,
            pickle,
            ser.getSerializerId(),
            flags,
            sequenceNr,
            annotations(),
            pyroHmacKey);
    Message resultmsg;
    synchronized (this.sock) {
      IOUtil.send(sock_out, msg.to_bytes());
      if (Config.MSG_TRACE_DIR != null) {
        Message.TraceMessageSend(
            sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
      }
      pickle = null;

      if ((flags & Message.FLAGS_ONEWAY) != 0) return null;

      resultmsg = Message.recv(sock_in, new int[] {Message.MSG_RESULT}, pyroHmacKey);
    }
    if (resultmsg.seq != sequenceNr) {
      throw new PyroException("result msg out of sync");
    }
    responseAnnotations(resultmsg.annotations, resultmsg.type);
    if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0) {
      _decompressMessageData(resultmsg);
    }
    if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0) {
      Throwable rx = (Throwable) ser.deserializeData(resultmsg.data);
      if (rx instanceof PyroException) {
        throw (PyroException) rx;
      } else {
        PyroException px = new PyroException("remote exception occurred", rx);
        try {
          Field remotetbField = rx.getClass().getDeclaredField("_pyroTraceback");
          String remotetb = (String) remotetbField.get(rx);
          px._pyroTraceback = remotetb;
        } catch (Exception e) {
          // exception didn't provide a pyro remote traceback
        }
        throw px;
      }
    }
    return ser.deserializeData(resultmsg.data);
  }