Пример #1
0
  /**
   * Invokes a method in all members and expects responses from members contained in dests (or all
   * members if dests is null).
   *
   * @param dests A list of addresses. If null, we'll wait for responses from all cluster members
   * @param method_call The method (plus args) to be invoked
   * @param options A collection of call options, e.g. sync versus async, timeout etc
   * @param listener A FutureListener which will be registered (if non null) with the future
   *     <em>before</em> the call is invoked
   * @return NotifyingFuture A future from which the results can be fetched
   * @throws Exception If the sending of the message threw an exception. Note that <em>no</em>
   *     exception will be thrown if any of the target members threw an exception; such an exception
   *     will be in the Rsp element for the particular member in the RspList
   */
  public <T> NotifyingFuture<RspList<T>> callRemoteMethodsWithFuture(
      Collection<Address> dests,
      MethodCall method_call,
      RequestOptions options,
      FutureListener<RspList<T>> listener)
      throws Exception {
    if (dests != null && dests.isEmpty()) { // don't send if dest list is empty
      if (log.isTraceEnabled())
        log.trace(
            "destination list of %s() is empty: no need to send message", method_call.getName());
      return new NullFuture<>(new RspList());
    }

    if (log.isTraceEnabled())
      log.trace("dests=%s, method_call=%s, options=%s", dests, method_call, options);

    Buffer buf =
        req_marshaller != null
            ? req_marshaller.objectToBuffer(method_call)
            : Util.objectToBuffer(method_call);
    Message msg = new Message().setBuffer(buf);

    NotifyingFuture<RspList<T>> retval = super.castMessageWithFuture(dests, msg, options, listener);
    if (log.isTraceEnabled()) log.trace("responses: %s", retval);
    return retval;
  }
Пример #2
0
  /**
   * Message contains MethodCall. Execute it against *this* object and return result. Use
   * MethodCall.invoke() to do this. Return result.
   */
  public Object handle(Message req) throws Exception {
    if (server_obj == null) {
      log.error(Util.getMessage("NoMethodHandlerIsRegisteredDiscardingRequest"));
      return null;
    }

    if (req == null || req.getLength() == 0) {
      log.error(Util.getMessage("MessageOrMessageBufferIsNull"));
      return null;
    }

    Object body =
        req_marshaller != null
            ? req_marshaller.objectFromBuffer(req.getRawBuffer(), req.getOffset(), req.getLength())
            : req.getObject();

    if (!(body instanceof MethodCall))
      throw new IllegalArgumentException("message does not contain a MethodCall object");

    MethodCall method_call = (MethodCall) body;

    if (log.isTraceEnabled()) log.trace("[sender=%s], method_call: %s", req.getSrc(), method_call);

    if (method_call.getMode() == MethodCall.ID) {
      if (method_lookup == null)
        throw new Exception(
            String.format(
                "MethodCall uses ID=%d, but method_lookup has not been set", method_call.getId()));
      Method m = method_lookup.findMethod(method_call.getId());
      if (m == null) throw new Exception("no method found for " + method_call.getId());
      method_call.setMethod(m);
    }

    return method_call.invoke(server_obj);
  }
Пример #3
0
  /**
   * Message contains MethodCall. Execute it against *this* object and return result. Use
   * MethodCall.invoke() to do this. Return result.
   */
  public Object handle(Message req) {
    Object body;
    MethodCall method_call;

    if (server_obj == null) {
      if (log.isErrorEnabled()) log.error("no method handler is registered. Discarding request.");
      return null;
    }

    if (req == null || req.getLength() == 0) {
      if (log.isErrorEnabled()) log.error("message or message buffer is null");
      return null;
    }

    try {
      body =
          req_marshaller != null
              ? req_marshaller.objectFromByteBuffer(
                  req.getBuffer(), req.getOffset(), req.getLength())
              : req.getObject();
    } catch (Throwable e) {
      if (log.isErrorEnabled()) log.error("exception marshalling object", e);
      return e;
    }

    if (!(body instanceof MethodCall)) {
      if (log.isErrorEnabled()) log.error("message does not contain a MethodCall object");

      // create an exception to represent this and return it
      return new IllegalArgumentException("message does not contain a MethodCall object");
    }

    method_call = (MethodCall) body;

    try {
      if (log.isTraceEnabled())
        log.trace("[sender=" + req.getSrc() + "], method_call: " + method_call);

      if (method_call.getMode() == MethodCall.ID) {
        if (method_lookup == null)
          throw new Exception(
              "MethodCall uses ID=" + method_call.getId() + ", but method_lookup has not been set");
        Method m = method_lookup.findMethod(method_call.getId());
        if (m == null) throw new Exception("no method found for " + method_call.getId());
        method_call.setMethod(m);
      }

      return method_call.invoke(server_obj);
    } catch (Throwable x) {
      return x;
    }
  }
Пример #4
0
  /**
   * Invokes a method in all members contained in dests (or all members if dests is null).
   *
   * @param dests A list of addresses. If null, the method will be invoked on all cluster members
   * @param method_call The method (plus args) to be invoked
   * @param options A collection of call options, e.g. sync versus async, timeout etc
   * @return RspList A list of return values and flags (suspected, not received) per member
   * @since 2.9
   */
  public RspList callRemoteMethods(
      Collection<Address> dests, MethodCall method_call, RequestOptions options) {
    if (dests != null && dests.isEmpty()) { // don't send if dest list is empty
      if (log.isTraceEnabled())
        log.trace(
            new StringBuilder("destination list of ")
                .append(method_call.getName())
                .append("() is empty: no need to send message"));
      return RspList.EMPTY_RSP_LIST;
    }

    if (log.isTraceEnabled())
      log.trace(
          new StringBuilder("dests=")
              .append(dests)
              .append(", method_call=")
              .append(method_call)
              .append(", options=")
              .append(options));

    Object buf;
    try {
      buf =
          req_marshaller != null
              ? req_marshaller.objectToBuffer(method_call)
              : Util.objectToByteBuffer(method_call);
    } catch (Exception e) {
      // if(log.isErrorEnabled()) log.error("exception", e);
      // we will change this in 3.0 to add the exception to the signature
      // (see http://jira.jboss.com/jira/browse/JGRP-193). The reason for a RTE is that we cannot
      // change the
      // signature in 2.3, otherwise 2.3 would be *not* API compatible to prev releases
      throw new RuntimeException("failure to marshal argument(s)", e);
    }

    Message msg = new Message();
    if (buf instanceof Buffer) msg.setBuffer((Buffer) buf);
    else msg.setBuffer((byte[]) buf);

    msg.setFlag(options.getFlags());
    if (options.getScope() > 0) msg.setScope(options.getScope());

    RspList retval = super.castMessage(dests, msg, options);
    if (log.isTraceEnabled()) log.trace("responses: " + retval);
    return retval;
  }
Пример #5
0
 public Buffer objectToBuffer(Object obj) throws Exception {
   MethodCall call = (MethodCall) obj;
   ByteBuffer buf;
   switch (call.getId()) {
     case START:
     case GET_CONFIG:
       buf = ByteBuffer.allocate(Global.BYTE_SIZE);
       buf.put((byte) call.getId());
       return new Buffer(buf.array());
     case SET_OOB:
     case SET_SYNC:
       return new Buffer(booleanBuffer(call.getId(), (Boolean) call.getArgs()[0]));
     case SET_NUM_MSGS:
     case SET_NUM_THREADS:
     case SET_MSG_SIZE:
     case SET_ANYCAST_COUNT:
       return new Buffer(intBuffer(call.getId(), (Integer) call.getArgs()[0]));
     case GET:
       return new Buffer(longBuffer(call.getId(), (Long) call.getArgs()[0]));
     case PUT:
       Long long_arg = (Long) call.getArgs()[0];
       byte[] arg2 = (byte[]) call.getArgs()[1];
       buf =
           ByteBuffer.allocate(
               Global.BYTE_SIZE + Global.INT_SIZE + Global.LONG_SIZE + arg2.length);
       buf.put((byte) call.getId())
           .putLong(long_arg)
           .putInt(arg2.length)
           .put(arg2, 0, arg2.length);
       return new Buffer(buf.array());
     case SET_READ_PERCENTAGE:
       Double double_arg = (Double) call.getArgs()[0];
       buf = ByteBuffer.allocate(Global.BYTE_SIZE + Global.DOUBLE_SIZE);
       buf.put((byte) call.getId()).putDouble(double_arg);
       return new Buffer(buf.array());
     default:
       throw new IllegalStateException("method " + call.getMethod() + " not known");
   }
 }