예제 #1
0
 public MultiCastNode(final long nodeId) throws IOException {
   try {
     this.nodeId = nodeId;
     this.groupAddress = InetAddress.getByAddress(GROUP_ADDRESS);
     if (LOG.isDebugEnabled()) {
       LOG.debug(
           "Initializing MultiCastNode for "
               + nodeId
               + " and group address "
               + groupAddress
               + ".");
     }
     setRunning(true);
     makePrivateSocket();
     startPrivateListener();
     joinGroup();
     startGroupListener();
     final MultiCastMessage hiMessage =
         new MultiCastMessage(nodeId, MultiCastMessage.Type.HI, getSender());
     sendToGroup(hiMessage);
     if (LOG.isDebugEnabled()) {
       LOG.debug("Done initializing MultiCastNode for " + this.nodeId);
     }
   } catch (IOException e) {
     setRunning(false);
     throw e;
   }
 }
예제 #2
0
 /**
  * Sends a private message.
  *
  * @param message message
  * @param address address to send the message to
  * @param port port to send the message to
  * @throws IOException if sending fails
  */
 private void sendPrivateMessage(
     final MultiCastMessage message, final InetAddress address, final int port)
     throws IOException {
   privateSocket.send(toDatagramPacket(message.toString(), address, port));
   if (LOG.isDebugEnabled()) {
     LOG.debug("Sent " + message + " to " + address + ":" + port);
   }
 }
예제 #3
0
 /** Stops all listeners. */
 public void stop() {
   if (LOG.isInfoEnabled()) {
     LOG.info(BUNDLE_MARKER, "Shutting down node " + this.nodeId);
   }
   // not necessary - we remove the node on the directoty level
   // sendToGroup(BYE + " " + nodeId);
   setRunning(false);
 }
예제 #4
0
 /**
  * Join the broadcast group.
  *
  * @throws IOException if something goes wrong
  */
 private void joinGroup() throws IOException {
   groupSocket = new MulticastSocket(GROUP_PORT);
   groupSocket.joinGroup(groupAddress);
   if (LOG.isDebugEnabled()) {
     LOG.debug(
         "MultiCastNode for " + nodeId + " joined group at " + groupAddress + ":" + GROUP_PORT);
   }
 }
예제 #5
0
 /**
  * Fires message to all registered listeners.
  *
  * @param multiCastMessage message
  */
 private void fireMessage(final MultiCastMessage multiCastMessage) {
   for (final MultiCastMessageListener multiCastMessageListener : multiCastMessageListeners) {
     multiCastMessageListener.processMessage(multiCastMessage);
   }
   if (multiCastMessageListeners.isEmpty() && LOG.isDebugEnabled()) {
     LOG.debug(BUNDLE_MARKER, "No MultiCastMessageListeners registered.");
   }
 }
예제 #6
0
 /** Receive loop for private messaqes. Can be stopped with {@link #setRunning(boolean)} */
 private void receivePrivateMessages() {
   while (isRunning()) {
     try {
       final byte[] buf = new byte[BUFFER_SIZE];
       final DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
       if (LOG.isDebugEnabled()) {
         LOG.debug(
             "Waiting for private message, listening on port " + privateSocket.getLocalPort());
       }
       privateSocket.receive(receivePacket); // wait for a packet
       final String data = toString(receivePacket);
       if (LOG.isDebugEnabled()) {
         LOG.debug("Got a private message: " + data);
       }
       if (LOG.isDebugEnabled()) {
         LOG.debug(
             "Received "
                 + data
                 + " from "
                 + receivePacket.getAddress()
                 + ":"
                 + receivePacket.getPort()
                 + ".");
       }
       processPrivateMessage(data);
     } catch (IOException e) {
       LOG.error(BUNDLE_MARKER, e.toString(), e);
     }
   }
   if (LOG.isDebugEnabled()) {
     LOG.debug("Stopped listening to private messages.");
   }
 }
예제 #7
0
 /**
  * Is notified of multicast messages. These messages are sent to the group, if their direction is
  * {@link org.bundlebee.registry.net.MultiCastMessage.Direction#OUT}.
  *
  * @param multiCastMessage multiCastMessage
  */
 public void processMessage(final MultiCastMessage multiCastMessage) {
   if (Direction.OUT.equals(multiCastMessage.getDirection())) {
     this.sendToGroup(multiCastMessage);
   } else {
     if (LOG.isDebugEnabled()) {
       LOG.debug(
           "Not sending message, because its direction is not "
               + Direction.OUT
               + ", but "
               + multiCastMessage.getDirection());
     }
   }
 }
예제 #8
0
 /**
  * Send a packet to the multicast group. Messages have the form (name): msg
  *
  * @param message message
  */
 public void sendToGroup(final String message) {
   try {
     if (LOG.isInfoEnabled()) {
       LOG.info(BUNDLE_MARKER, "Sending packet to group: " + message);
     }
     final DatagramPacket sendPacket = toDatagramPacket(message, groupAddress, GROUP_PORT);
     groupSocket.send(sendPacket);
     if (LOG.isInfoEnabled()) {
       LOG.info(BUNDLE_MARKER, "Packet sent to group: " + message);
     }
   } catch (IOException ioe) {
     LOG.error(BUNDLE_MARKER, "Failed to send packet: " + ioe.toString(), ioe);
   }
 }
예제 #9
0
  /**
   * Checks if the LOCAL_PORT is availible. If not try another one.
   *
   * @param startport Start port, try first to open.
   * @return a DatagramSocket for the Registry.
   */
  private static DatagramSocket getAvailableSocket(final int startport) throws SocketException {

    SocketException lastex = null;
    for (int port = startport; port < LOCAL_PORT + MAX_PORT_RANGE; port++) {

      try {
        DatagramSocket ds = new DatagramSocket(port);
        LOG.info("LOCAL_PORT=" + port);
        return ds;
      } catch (SocketException e) {
        lastex = e;
        LOG.info("LOCAL_PORT " + port + " already in use - trying " + (port + 1));
      }
    }
    throw lastex;
  }
예제 #10
0
 private static int getIntSystemProperty(final int defaultValue, final String key) {
   try {
     return Integer.parseInt(System.getProperty(key, "" + defaultValue));
   } catch (NumberFormatException e) {
     LOG.error(BUNDLE_MARKER, e.toString(), e);
   }
   return defaultValue;
 }
예제 #11
0
 public void sendToGroup(final MultiCastMessage multiCastMessage) {
   if (multiCastMessage.isValid()) {
     // reset ls request count, when we send HI
     if (multiCastMessage.getType() == MultiCastMessage.Type.HI) {
       lsRequestSent = 0;
       // make sure we have a sender set
       // even if the directory does not know, who we are
       if (multiCastMessage.getValues().getProperty(MultiCastMessage.PROPERTYKEY_SENDER) == null) {
         multiCastMessage
             .getValues()
             .setProperty(MultiCastMessage.PROPERTYKEY_SENDER, getSender());
       }
     }
     sendToGroup(multiCastMessage.toString());
   } else {
     if (LOG.isDebugEnabled()) {
       LOG.debug(
           BUNDLE_MARKER, "not sending message, because it is not valid: " + multiCastMessage);
     }
   }
 }
예제 #12
0
 /**
  * Processes a message.
  *
  * @param message message
  * @throws IOException if something goes wrong
  */
 private void processGroupMessage(final String message) throws IOException {
   try {
     final MultiCastMessage multiCastMessage = new MultiCastMessage(message);
     if (multiCastMessage.getType() == MultiCastMessage.Type.HI
         && multiCastMessage.getNodeId() != RegistryImpl.getInstance().getNodeId()) {
       final InetAddress address = multiCastMessage.getSenderAddress();
       final int port = multiCastMessage.getSenderPort();
       // we don't use datagramPacket.getAddress(), because of
       // http://bugs.sun.com/view_bug.do?bug_id=4717228
       // -hendrik
       sendPrivateMessage(
           new MultiCastMessage(nodeId, MultiCastMessage.Type.HI, getSender()), address, port);
     }
     if (LOG.isInfoEnabled()) {
       LOG.info(BUNDLE_MARKER, "(NODE) processing node message: " + message);
     }
     if (multiCastMessage.isValid()) {
       multiCastMessage.setDirection(Direction.IN);
       fireMessage(multiCastMessage);
     }
   } catch (RuntimeException e) {
     LOG.error(BUNDLE_MARKER, "Failed to process group message: " + e.toString(), e);
   }
 }
예제 #13
0
 private static byte[] getFourByteSystemProperty(final byte[] defaultValue, final String key) {
   final String address = System.getProperty(key);
   if (address == null) {
     return defaultValue;
   }
   try {
     final String[] byteStrings = address.split("\\.");
     if (byteStrings.length != 4) {
       return defaultValue;
     }
     final byte[] bytes = new byte[4];
     for (int i = 0; i < bytes.length; i++) {
       bytes[i] = (byte) Integer.parseInt(byteStrings[i]);
     }
     return bytes;
   } catch (NumberFormatException e) {
     LOG.error(BUNDLE_MARKER, e.toString(), e);
   }
   return defaultValue;
 }
예제 #14
0
 /**
  * Processes a privately received message.
  *
  * @param message message
  * @throws IOException if a response request fails
  */
 private void processPrivateMessage(final String message) throws IOException {
   try {
     final MultiCastMessage multiCastMessage = new MultiCastMessage(message);
     if (multiCastMessage.getType() == MultiCastMessage.Type.LS) {
       final InetAddress address = multiCastMessage.getSenderAddress();
       final int port = multiCastMessage.getSenderPort();
       // sending everything to remote private port
       for (final MultiCastMessage mcm : ((RegistryImpl) RegistryImpl.getInstance()).getList()) {
         sendPrivateMessage(mcm, address, port);
       }
     } else if (multiCastMessage.getType() == MultiCastMessage.Type.HI) {
       final InetAddress address = multiCastMessage.getSenderAddress();
       final int port = multiCastMessage.getSenderPort();
       if (multiCastMessage.getNodeId() == RegistryImpl.getInstance().getNodeId()) {
         if (LOG.isDebugEnabled()) {
           LOG.debug("HI message is from this node, doing nothing.");
         }
       } else {
         if (lsRequestSent < maxLsRequests) {
           if (LOG.isDebugEnabled()) {
             LOG.debug("Sending ls request to " + address);
           }
           sendPrivateMessage(
               new MultiCastMessage(nodeId, MultiCastMessage.Type.LS, getSender()), address, port);
           lsRequestSent++;
         } else {
           if (LOG.isDebugEnabled()) {
             LOG.debug("Max ls requests already sent, doing nothing.");
           }
         }
       }
     } else {
       if (multiCastMessage.isValid()) {
         multiCastMessage.setDirection(Direction.IN);
         fireMessage(multiCastMessage);
       }
     }
   } catch (RuntimeException e) {
     LOG.error(BUNDLE_MARKER, "Failed to process private message: " + e.toString(), e);
   }
 }
예제 #15
0
 /**
  * Repeatedly receive a packet from the group, process it. No messages are sent from here.
  * sendPacket().
  */
 public void receiveGroupMessages() {
   if (LOG.isDebugEnabled()) {
     LOG.debug("Starting group receive loop for " + nodeId);
   }
   while (this.isRunning()) {
     try {
       final byte[] data = new byte[BUFFER_SIZE]; // set up an empty packet
       final DatagramPacket packet = new DatagramPacket(data, data.length);
       if (LOG.isDebugEnabled()) {
         LOG.debug("Waiting for group message on " + groupSocket);
       }
       groupSocket.receive(packet); // wait for a packet
       final String msg = toString(packet);
       if (LOG.isDebugEnabled()) {
         LOG.debug(
             "Received group msg "
                 + msg
                 + " from "
                 + packet.getAddress()
                 + ":"
                 + packet.getPort()
                 + ".");
       }
       processGroupMessage(msg);
     } catch (SocketTimeoutException e) {
       if (LOG.isInfoEnabled()) {
         LOG.info(BUNDLE_MARKER, "GroupSocket receive timed out.");
       }
     } catch (IOException e) {
       LOG.error(BUNDLE_MARKER, e.toString(), e);
     } catch (Throwable t) {
       LOG.error(BUNDLE_MARKER, t.toString(), t);
     }
   }
   if (LOG.isDebugEnabled()) {
     LOG.debug("Group receive loop for " + nodeId + " was stopped.");
   }
 }
예제 #16
0
 /**
  * Creates the socket used for private point to point communication between two nodes.
  *
  * @throws SocketException if the socket can't be created
  */
 private void makePrivateSocket() throws SocketException {
   this.privateSocket = getAvailableSocket(LOCAL_PORT);
   if (LOG.isDebugEnabled()) {
     LOG.debug("Bound private socket to port " + privateSocket.getLocalPort());
   }
 }