Пример #1
0
  /**
   * This is called remotely from other cluster members when a new remote subscription is
   * identified.
   *
   * <p>We add or remove a remote subscription...
   */
  public void subscribeFromPeer(
      String destinationId,
      Boolean subscribe,
      String selector,
      String subtopic,
      Object remoteAddress) {
    Destination destination = getDestination(destinationId);

    RemoteSubscriptionManager subMgr =
        ((MessageDestination) destination).getRemoteSubscriptionManager();

    if (destination instanceof MessageDestination) {
      if (debug)
        Log.getLogger(MessageService.LOG_CATEGORY)
            .debug(
                "Received subscription from peer: "
                    + remoteAddress
                    + " subscribe? "
                    + subscribe
                    + " selector: "
                    + selector
                    + " subtopic: "
                    + subtopic);
      if (subscribe) subMgr.addSubscriber(remoteAddress, selector, subtopic, null);
      else subMgr.removeSubscriber(remoteAddress, selector, subtopic, null);
    } else if (Log.isError())
      Log.getLogger(LOG_CATEGORY)
          .error(
              "subscribeFromPeer called with destination: "
                  + destinationId
                  + " that is not a MessageDestination");
  }
Пример #2
0
  @Override
  public void start() {
    String serviceType = getClass().getName();
    ClusterManager clm = getMessageBroker().getClusterManager();

    super.start();

    /*
     * For any destinations which are not using broadcast mode,
     * we need to init the remote subscriptions.  First we send out
     * the requestSubscription messages, then we wait for the sendSubscriptions
     * messages to come in.
     */
    for (String destName : destinations.keySet()) {
      MessageDestination dest = (MessageDestination) getDestination(destName);
      if (!dest.getServerSettings().isBroadcastRoutingMode() && dest.isClustered()) {
        initRemoteSubscriptions(destName);
      }
    }

    /* Now go through and wait for the response to these messages... */
    for (String destName : destinations.keySet()) {
      MessageDestination dest = (MessageDestination) getDestination(destName);
      if (!dest.getServerSettings().isBroadcastRoutingMode() && dest.isClustered()) {
        List members = clm.getClusterMemberAddresses(serviceType, destName);
        for (Object addr : members) {
          if (!clm.getLocalAddress(serviceType, destName).equals(addr)) {
            RemoteSubscriptionManager subMgr = dest.getRemoteSubscriptionManager();
            subMgr.waitForSubscriptions(addr);
          }
        }
      }
    }
    debug = Log.isDebug();
  }
Пример #3
0
  /**
   * This method is invoked remotely via jgroups. It builds a snapshot of the local subscription
   * state and sends it back to the requesting server by calling its receiveSubscriptions method.
   *
   * @exclude
   */
  public void sendSubscriptions(String destinationId, Object remoteAddress) {
    MessageDestination destination = (MessageDestination) getDestination(destinationId);
    Object subscriptions;

    /*
     * Avoid trying to use the cluster stuff if this destination does not
     * exist or is not clustered on this server.
     */
    if (destination == null) {
      if (Log.isError())
        Log.getLogger(LOG_CATEGORY)
            .error(
                "Destination: "
                    + destinationId
                    + " does not exist on this server but we received a request for the subscription info from a peer server where the destination exists as clustered.  Check the cluster configuration for this destination and make sure it matches on all servers.");
      return;
    } else if (!destination.isClustered()) {
      if (Log.isError())
        Log.getLogger(LOG_CATEGORY)
            .error(
                "Destination: "
                    + destinationId
                    + " is not clustered on this server but we received a request for the subscription info from a peer server which is clustered.  Check the cluster configuration for this destination and make sure it matches on all servers.");
      return;
    }

    RemoteSubscriptionManager subMgr = destination.getRemoteSubscriptionManager();

    /*
     * The remote server has no subscriptions initially since it has not
     * started yet.  We initialize the server here so that when it sends
     * the first add subscription request, we'll receive it.  This is because
     * servers will not process remote add/remove subscribe requests until
     * they have received the subscription state from each server.
     */
    subMgr.setSubscriptionState(Collections.EMPTY_LIST, remoteAddress);

    /*
     * To ensure that we send the remote server a clean copy of the subscription
     * table we need to block out the code which adds/removes subscriptions and sends
     * them to remote servers between here...
     */
    try {
      subscribeLock.writeLock().lock();
      subscriptions = destination.getSubscriptionManager().getSubscriptionState();
      ClusterManager clm = getMessageBroker().getClusterManager();
      clm.invokePeerToPeerOperation(
          getClass().getName(),
          destinationId,
          "receiveSubscriptions",
          new Object[] {destinationId, subscriptions},
          remoteAddress);
    } finally {
      /* ... And here */
      subscribeLock.writeLock().unlock();
    }
  }
Пример #4
0
  /**
   * Same as the previous method but it accepts a destination parameter as well to avoid potentially
   * costly destination lookup.
   *
   * @param message The <code>Message</code> to push to peer server nodes in the cluster.
   * @param destination The destination to push the message to.
   * @param evalSelector <code>true</code> to evaluate each remote subscriber's selector before
   *     pushing the message to them; <code>false</code> to skip selector evaluation.
   */
  public void sendPushMessageFromPeer(
      Message message, MessageDestination destination, boolean evalSelector) {
    if (!destination.isClustered()) return;

    ClusterManager clm = getMessageBroker().getClusterManager();
    if (destination.getServerSettings().isBroadcastRoutingMode()) {
      if (debug)
        Log.getLogger(LOG_CATEGORY)
            .debug(
                "Broadcasting message to peer servers: "
                    + message
                    + " evalSelector: "
                    + evalSelector);
      // tell the message service on other nodes to push the message
      clm.invokeServiceOperation(
          getClass().getName(),
          message.getDestination(),
          "pushMessageFromPeer",
          new Object[] {message, evalSelector});
    } else {
      RemoteSubscriptionManager mgr = destination.getRemoteSubscriptionManager();
      Set serverAddresses = mgr.getSubscriberIds(message, evalSelector);

      if (debug)
        Log.getLogger(LOG_CATEGORY)
            .debug(
                "Sending message to peer servers: "
                    + serverAddresses
                    + StringUtils.NEWLINE
                    + " message: "
                    + message
                    + StringUtils.NEWLINE
                    + " evalSelector: "
                    + evalSelector);

      for (Object remoteAddress : serverAddresses) {
        clm.invokePeerToPeerOperation(
            getClass().getName(),
            message.getDestination(),
            "pushMessageFromPeerToPeer",
            new Object[] {message, evalSelector},
            remoteAddress);
      }
    }
  }