Package org.hive2hive.core.processes.implementations.notify

Source Code of org.hive2hive.core.processes.implementations.notify.SendNotificationsMessageStep

package org.hive2hive.core.processes.implementations.notify;

import java.security.PublicKey;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.tomp2p.peers.PeerAddress;

import org.hive2hive.core.exceptions.NoPeerConnectionException;
import org.hive2hive.core.exceptions.SendFailedException;
import org.hive2hive.core.network.NetworkManager;
import org.hive2hive.core.network.NetworkUtils;
import org.hive2hive.core.network.data.DataManager;
import org.hive2hive.core.network.messages.direct.BaseDirectMessage;
import org.hive2hive.core.network.messages.direct.response.ResponseMessage;
import org.hive2hive.core.processes.framework.exceptions.InvalidProcessStateException;
import org.hive2hive.core.processes.implementations.common.GetUserLocationsStep;
import org.hive2hive.core.processes.implementations.common.base.BaseDirectMessageProcessStep;
import org.hive2hive.core.processes.implementations.context.NotifyProcessContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SendNotificationsMessageStep extends BaseDirectMessageProcessStep {

  private final static Logger logger = LoggerFactory.getLogger(SendNotificationsMessageStep.class);
  private final NotifyProcessContext context;
  private final NetworkManager networkManager;
  private final Set<PeerAddress> unreachablePeers;

  public SendNotificationsMessageStep(NotifyProcessContext context, NetworkManager networkManager)
      throws NoPeerConnectionException {
    super(networkManager.getMessageManager());
    this.context = context;
    this.networkManager = networkManager;
    this.unreachablePeers = new HashSet<PeerAddress>();
  }

  @Override
  protected void doExecute() throws InvalidProcessStateException {
    BaseNotificationMessageFactory messageFactory = context.consumeMessageFactory();
    Map<String, PublicKey> userPublicKeys = context.getUserPublicKeys();
    Map<String, List<PeerAddress>> locations = context.getAllLocations();

    for (String user : context.consumeUsersToNotify()) {
      PublicKey publicKey = userPublicKeys.get(user);
      List<PeerAddress> peerAddresses = locations.get(user);
      if (user.equalsIgnoreCase(networkManager.getUserId())) {
        // send own peers a 'normal' notification message
        notifyMyPeers(peerAddresses, messageFactory, publicKey);
      } else {
        // send to the initial node of another client
        notifyMasterPeer(peerAddresses, messageFactory, user, publicKey);
      }
    }

    if (!unreachablePeers.isEmpty()) {
      logger.debug("Need to cleanup {} unreachable peers of own user", unreachablePeers.size());
      initCleanupUnreachablePeers();
    }
  }

  private void notifyMyPeers(List<PeerAddress> ownPeers, BaseNotificationMessageFactory messageFactory,
      PublicKey ownPublicKey) {
    ownPeers.remove(networkManager.getConnection().getPeer().getPeerAddress());
    logger.debug("Notifying {} other peers of me (without myself).", ownPeers.size());
    for (PeerAddress peerAddress : ownPeers) {
      if (peerAddress.equals(networkManager.getConnection().getPeer().getPeerAddress())) {
        // don't send myself
        logger.trace("Skipping to send a message to myself.");
        continue;
      }

      try {
        BaseDirectMessage message = messageFactory.createPrivateNotificationMessage(peerAddress);
        if (message == null) {
          logger.info("Not notifying any of the own peers because the message to be sent is null.");
        } else {
          sendDirect(message, ownPublicKey);
        }
      } catch (SendFailedException e) {
        // add to the unreachable list, such that the next step can cleanup those locations
        unreachablePeers.add(peerAddress);
        // continue anyhow
      }
    }
  }

  private void notifyMasterPeer(List<PeerAddress> peerList, BaseNotificationMessageFactory messageFactory, String userId,
      PublicKey publicKey) {
    boolean success = false;
    while (!success && !peerList.isEmpty()) {
      PeerAddress initial = NetworkUtils.choseFirstPeerAddress(peerList);
      BaseDirectMessage msg = messageFactory.createHintNotificationMessage(initial, userId);
      try {
        sendDirect(msg, publicKey);
        success = true;
      } catch (SendFailedException e) {
        if (!peerList.isEmpty()) {
          logger.error("Initial peer of user '{}' was offline. Try next in line.", userId);
          peerList.remove(0);
        }
      }
    }

    if (success) {
      logger.debug("Successfully notified the initial peer of user '{}' that it should check its UP tasks.", userId);
    } else {
      logger.info("All clients of user '{}' are currently offline or unreachable.", userId);
    }
  }

  private void initCleanupUnreachablePeers() {
    try {
      DataManager dataManager = networkManager.getDataManager();
      getParent().add(new GetUserLocationsStep(networkManager.getUserId(), context, dataManager));
      getParent().add(new RemoveUnreachableStep(context, unreachablePeers, networkManager));
    } catch (NoPeerConnectionException e) {
      logger.error("No connection to the network. Failed to cleanup unreachable peers");
    }
  }

  @Override
  public void handleResponseMessage(ResponseMessage responseMessage) {
    // no response expected
  }
}
TOP

Related Classes of org.hive2hive.core.processes.implementations.notify.SendNotificationsMessageStep

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.