Пример #1
0
  protected void onForwardMessage(Map<String, Object> data, boolean broadcast) {
    logger.debug("Received {} action {}", broadcast ? "broadcast" : "forwarded", data);
    Map<String, Object> resultData = new HashMap<>(3);
    resultData.put(ID_FIELD, data.get(ID_FIELD));
    resultData.put(OORT_URL_FIELD, getOort().getURL());
    String oortURL = (String) data.get(OORT_URL_FIELD);
    try {
      Result<R> result = onForward(new Request(oort.getURL(), data.get(PARAMETER_FIELD), oortURL));
      logger.debug("Forwarded action result {}", result);
      if (result.succeeded()) {
        resultData.put(RESULT_FIELD, true);
        resultData.put(DATA_FIELD, result.data);
      } else if (result.failed()) {
        resultData.put(RESULT_FIELD, false);
        resultData.put(DATA_FIELD, result.data);
      } else {
        if (broadcast) {
          // Ignore and therefore return
          logger.debug("Ignoring broadcast action result {}", result);
          return;
        } else {
          // Convert ignore into failure
          resultData.put(RESULT_FIELD, false);
          resultData.put(DATA_FIELD, result.data);
        }
      }
    } catch (Exception x) {
      if (broadcast) return;

      String failure = x.getMessage();
      if (failure == null || failure.length() == 0) failure = x.getClass().getName();
      resultData.put(RESULT_FIELD, false);
      resultData.put(DATA_FIELD, failure);
    }

    if (getOort().getURL().equals(oortURL)) {
      // Local case
      logger.debug("Returning forwarded action result {} to local {}", resultData, oortURL);
      onResultMessage(resultData);
    } else {
      // Remote case
      OortComet comet = getOort().getComet(oortURL);
      if (comet != null) {
        logger.debug("Returning forwarded action result {} to remote {}", resultData, oortURL);
        comet.getChannel(resultChannelName).publish(resultData);
      } else {
        // Probably the node disconnected concurrently
        logger.debug(
            "Could not return forwarded action result {} to remote {}", resultData, oortURL);
      }
    }
  }
Пример #2
0
  /**
   * Subclasses must call this method to forward the action to the owner node.
   *
   * <p>If the {@code targetOortURL} is {@code null}, then the action is broadcast to all nodes.
   * Nodes that receive an action request that they can't fullfill because they don't own the entity
   * the action should be applied to must return {@link Result#ignore(Object)}.
   *
   * @param targetOortURL the owner node Oort URL, or null to broadcast the action to all nodes
   * @param parameter the action parameter that will be passed to {@link #onForward(Request)}
   * @param context the opaque context passed to {@link #onForwardSucceeded(Object, Object)}
   * @return whether the forward succeeded
   */
  protected boolean forward(String targetOortURL, Object parameter, C context) {
    Map<String, Object> ctx = new HashMap<>(4);
    long contextId = contextIds.incrementAndGet();
    ctx.put(ID_FIELD, contextId);
    ctx.put(CONTEXT_FIELD, context);
    callbacks.put(contextId, ctx);

    Map<String, Object> data = new HashMap<>(3);
    data.put(ID_FIELD, contextId);
    data.put(PARAMETER_FIELD, parameter);
    String localOortURL = getOort().getURL();
    data.put(OORT_URL_FIELD, localOortURL);

    if (targetOortURL == null) {
      // Application does not know where the entity is, broadcast
      if (logger.isDebugEnabled()) {
        logger.debug("Broadcasting action: {}", data);
      }
      startTimeout(ctx);
      oort.getBayeuxServer().getChannel(broadcastChannelName).publish(getLocalSession(), data);
      return true;
    } else {
      if (localOortURL.equals(targetOortURL)) {
        // Local case
        if (logger.isDebugEnabled()) {
          logger.debug("Forwarding action locally ({}): {}", localOortURL, data);
        }
        startTimeout(ctx);
        onForwardMessage(data, false);
        return true;
      } else {
        // Remote case
        OortComet comet = getOort().getComet(targetOortURL);
        if (comet != null) {
          if (logger.isDebugEnabled()) {
            logger.debug("Forwarding action from {} to {}: {}", localOortURL, targetOortURL, data);
          }
          startTimeout(ctx);
          comet.getChannel(forwardChannelName).publish(data);
          return true;
        } else {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "Could not forward action from {} to {}: {}", localOortURL, targetOortURL, data);
          }
          return false;
        }
      }
    }
  }
Пример #3
0
 protected void receive(String cometURL) {
   if (!oort.getKnownComets().contains(cometURL)) {
     if (logger.isDebugEnabled()) logger.debug("Received comet URL via multicast: {}", cometURL);
     OortComet oortComet = oort.observeComet(cometURL);
     if (oortComet != null) {
       boolean elapsed =
           !oortComet.waitFor(
               getConnectTimeout(), BayeuxClient.State.CONNECTED, BayeuxClient.State.DISCONNECTED);
       // If we could not connect, let's disconnect, we will be advertised again
       if (elapsed) {
         if (logger.isDebugEnabled())
           logger.debug("Interrupting attempts to connect to {}", cometURL);
         oort.deobserveComet(cometURL);
       }
     }
   }
 }