Example #1
0
  @Override
  public void onReconnected() {
    log.info("reconnected");
    if (mode.contains(MODE.RESEND_SUBSCRIBE_ON_RECONNECTED)) {

      Set<String> channels;

      // channel as sourceDispatcherId
      channels = new HashSet<String>();
      channels.add(getSourceDispatcherId());
      driverImpl.subscribeChannels(channels);

      // channels as object_IDs registered with localObjectsMap
      channels = localObjectsMap.keySet();
      if (!channels.isEmpty()) {
        driverImpl.subscribeChannels(channels);
      }

      // all channels registered with subscribersMap
      channels = subscribersMap.getSubscribedChannels();
      if (!channels.isEmpty()) {
        driverImpl.subscribeChannels(channels);
      }

      // re-SUBSCRIBE completed with all the registered channels.
      pubSubDriverSuspended = false; // Resumed
    } else {
      // You may add some code here to inform other objects that
      // the network connectivity has resumed or the pubsub server
      // has become available.
    }
  }
Example #2
0
 /**
  * Adds a local object as a listener of messages.
  *
  * <p>The user (i.e., RemoteObject) of this class calls this method to register the RemoteObject
  * as "local RemoteObject" with this class.
  *
  * <pre>
  *   [RemoteObject]    [RemoteObject]    [RemoteObject]
  *   dispatchEvent()  dispatchRequest() dispatchRequest()
  *         ^                 ^                 ^
  *         |                 |                 |
  *         +---------------+ + +---------------+
  *                         | | |
  *                  [MessageDispatcher]<>-----[SubscribersMap]
  *                           |
  *                        message
  *                           |
  *                    [pubsub server]
  * </pre>
  *
  * <p>This method also sends "SUBSCRIBE own-object-ID-as-channel" to pubsub server to receive
  * PUBLISH destined to the remote object, since requestSync() method sends PUBLISH as "request" to
  * the remote object.
  *
  * @param localObject a remote object
  * @see org.o3project.odenos.remoteobject.RemoteObject#dispatchEvent
  * @see org.o3project.odenos.remoteobject.RemoteObject#dispatchRequest
  */
 public void addLocalObject(RemoteObject localObject) {
   String objectId = localObject.getObjectId();
   if (localObjectsMap.putIfAbsent(objectId, localObject) == null) {
     driverImpl.subscribeChannel(objectId);
   }
   if (objectId.equals(systemManagerId)) {
     driverImpl.systemManagerAttached();
   }
 }
Example #3
0
 /**
  * Asynchronous event publication service for requestSync().
  *
  * <p>The response eventually reaches its originating method (requestSync()) via
  * RemoteMessageTransport.
  */
 public void publishResponseAsync(
     final int sno, final String channel, final Request request, final Response response)
     throws IOException {
   BufferPacker pk = msgpack.createBufferPacker();
   // write delivery header.
   pk.write(TYPE_RESPONSE);
   pk.write(sno);
   pk.write(request.objectId);
   // write delivery body.
   pk.write(response);
   byte[] message = pk.toByteArray();
   // PUBLISH
   driverImpl.publish(channel, message);
   if (log.isDebugEnabled()) {
     log.debug(
         "Response returned:\n"
             + "  MessageDispatcher: {}\n"
             + "  channel: {}\n"
             + "  statusCode: {}\n"
             + "  body: {}",
         sourceDispatcherId,
         channel,
         response.statusCode,
         response.getBodyValue());
   }
 }
Example #4
0
 /**
  * Asynchronous event publication service for requestSync().
  *
  * <p>requestSync() turns into this method via RemoteMessageTransport.
  *
  * <p>Remote objects uses this method to publish a request as event asynchronously.
  *
  * <p>Although this method is asynchronous, {@link RemoteTransactions} provides a synchronous
  * method to wait for a response from another remote object.
  */
 protected void publishRequestAsync(final int sno, final Request request) throws IOException {
   BufferPacker pk = msgpack.createBufferPacker();
   // write delivery header.
   pk.write(TYPE_REQUEST);
   pk.write(sno);
   pk.write(getSourceDispatcherId());
   // write delivery body.
   pk.write(request);
   byte[] message = pk.toByteArray();
   String channel = request.objectId;
   // PUBLISH
   driverImpl.publish(channel, message);
   if (log.isDebugEnabled()) {
     log.debug(
         "Request sent:\n"
             + "  MessageDispatcher: {}\n"
             + "  sno: {}\n"
             + "  channel: {}\n"
             + "  method: {}\n"
             + "  objectId: {}\n"
             + "  path: /{}/\n"
             + "  body: {}",
         sourceDispatcherId,
         sno,
         channel,
         request.method,
         request.objectId,
         request.path,
         request.getBodyValue());
   }
 }
Example #5
0
 /**
  * Removes a local object.
  *
  * <p>This method also sends "UNSUBSCRIBE own-object-ID-as-channel" to pubsub server to stop
  * receiving PUBLISH destined to the remote object.
  *
  * @param localObject a remote object
  */
 public void removeLocalObject(RemoteObject localObject) {
   String objectId = localObject.getObjectId();
   if (localObjectsMap.remove(objectId) != null) {
     // Unsubscribes objectId as a channel to stop receiving Request
     // from remote objects via PubSub.
     driverImpl.unsubscribeChannel(objectId);
   }
 }
Example #6
0
 /**
  * Closes the services.
  *
  * <p>You can also do "try-with-resources" to automatically close this class.
  */
 public void close() {
   // TODO: Graceful termination of all the components and the transport
   // TODO: subscriptionFeeder termination
   driverImpl.close();
   remoteTransactions.onFinalize();
   subscribersMap.clear();
   log.info("terminated");
 }
Example #7
0
  /**
   * Starts the services.
   *
   * <p>This method must be called after instantiating this class to start a {@link IPubSubDriver}
   * implementation class.
   */
  public void start() {

    // This method blocks until the connectivity with pubsub server
    // has become ready.
    driverImpl.start();

    // To receive Request from "remote" RemoteObject,
    // MessageDispatcher needs to register itself w/ pubsub server.
    driverImpl.subscribeChannel(sourceDispatcherId);

    // This thread feeds subscription info to EventManager
    // in an eventually-consistent manner.
    subscriptionFeeder =
        new Thread(
            new Runnable() {
              @Override
              public void run() {
                do {
                  Request request = null;
                  try {
                    request = eventManagerQueue.take();
                    Response response = requestSync(request);
                    if (response == null || !response.statusCode.equals(Response.OK)) {
                      log.warn("Unsuccessful transaction to EventManager: " + response.statusCode);
                    }
                  } catch (InterruptedException e) {
                    log.warn("Unsuccessful transaction to EventManager due to some internal error");
                  } catch (Exception e) {
                    log.warn("EventManager may be inactive");
                  }
                } while (true); // TODO: graceful thread termination
              }
            });
    subscriptionFeeder.start();

    log.info("started");
  }
Example #8
0
 /**
  * Channel unsubscription service.
  *
  * @param subscriberId subscriber's object ID
  * @param channelsToBeUnsubscribed channels to be unsubscribed
  */
 public void unsubscribeChannels(
     final String subscriberId, final Map<String, Set<String>> channelsToBeUnsubscribed) {
   Set<String> channels = new HashSet<>();
   for (String publisherId : channelsToBeUnsubscribed.keySet()) {
     Set<String> eventIds = channelsToBeUnsubscribed.get(publisherId);
     for (String eventId : eventIds) {
       String channel = channelString(publisherId, eventId);
       if (subscribersMap.removeSubscription(channel, subscriberId)) {
         channels.add(channel);
       }
     }
   }
   if (!channels.isEmpty() && !pubSubDriverSuspended) {
     driverImpl.unsubscribeChannels(channels);
   }
 }
Example #9
0
 /**
  * Asynchronous event publication service
  *
  * <p>Remote objects use this method to publish an event asynchronously.
  */
 public void publishEventAsync(final Event event) throws IOException {
   BufferPacker pk = msgpack.createBufferPacker();
   // write delivery header.
   pk.write(TYPE_EVENT);
   pk.write(0);
   pk.write("event");
   // write delivery body.
   pk.write(event);
   byte[] message = pk.toByteArray();
   String channel = channelString(event.publisherId, event.eventType);
   // PUBLISH
   driverImpl.publish(channel, message);
   if (log.isDebugEnabled()) {
     log.debug(
         "Event sent:\n" + "  MessageDispatcher: {}\n" + "  channel: {}\n" + "  body: {}",
         sourceDispatcherId,
         channel,
         event.getBodyValue());
   }
 }