package org.peerbox.app.manager.node; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Iterator; import java.util.List; import java.util.UUID; import org.hive2hive.core.api.H2HNode; import org.hive2hive.core.api.configs.FileConfiguration; import org.hive2hive.core.api.configs.NetworkConfiguration; import org.hive2hive.core.api.interfaces.IFileConfiguration; import org.hive2hive.core.api.interfaces.IH2HNode; import org.hive2hive.core.api.interfaces.INetworkConfiguration; import org.peerbox.events.MessageBus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; import com.google.inject.Singleton; @Singleton public final class NodeManager implements INodeManager { private static final Logger logger = LoggerFactory.getLogger(NodeManager.class); private final MessageBus messageBus; private IH2HNode node; private INetworkConfiguration networkConfiguration; private IFileConfiguration fileConfiguration; @Inject public NodeManager(final MessageBus messageBus) { this.messageBus = messageBus; } private String generateNodeID() { return UUID.randomUUID().toString(); } private synchronized void createNode() { fileConfiguration = FileConfiguration.createDefault(); node = H2HNode.createNode(fileConfiguration); } @Override public synchronized boolean joinNetwork(List<String> bootstrappingNodes) { boolean connected = false; Iterator<String> nodeIt = bootstrappingNodes.iterator(); while (nodeIt.hasNext() && !connected) { String node = nodeIt.next(); boolean res = false; try { res = joinNetwork(node); connected = isConnected(); if (res && connected) { logger.debug("Successfully connected to node {}", node); } else { logger.debug("Could not connect to node {}", node); } } catch(UnknownHostException e) { logger.warn("Address of host could not be determined: {}", node); res = false; connected = false; } } return connected; } @Override public synchronized boolean joinNetwork(final String address) throws UnknownHostException { if (address.isEmpty()) { throw new IllegalArgumentException("Bootstrap address is empty."); } createNode(); String nodeID = generateNodeID(); InetAddress bootstrapInetAddress = InetAddress.getByName(address); networkConfiguration = NetworkConfiguration.create(nodeID, bootstrapInetAddress); boolean success = node.connect(networkConfiguration); success = success && isConnected(); if (success) { notifyConnect(address); } return success; } @Override public synchronized boolean createNetwork() { createNode(); String nodeID = generateNodeID(); networkConfiguration = NetworkConfiguration.createInitial(nodeID); boolean success = node.connect(networkConfiguration); success = success && isConnected(); if (success) { notifyConnect("localhost"); } return success; } private void notifyConnect(final String address) { if (messageBus != null) { messageBus.publish(new NodeConnectMessage(address)); } } @Override public synchronized boolean leaveNetwork() { if (node != null) { boolean res = node.disconnect(); node = null; notifyDisconnect(); return res; } return true; } private void notifyDisconnect() { if (messageBus != null) { messageBus.publish(new NodeDisconnectMessage()); } } @Override public boolean isConnected() { return node != null && node.isConnected(); } @Override public IH2HNode getNode() { return node; } @Override public INetworkConfiguration getNetworkConfiguration() { return networkConfiguration; } @Override public IFileConfiguration getFileConfiguration() { return fileConfiguration; } }