Package org.hornetq.api.core

Source Code of org.hornetq.api.core.UDPBroadcastGroupConfiguration$UDPBroadcastEndpoint

/*
* Copyright 2005-2014 Red Hat, Inc.
* Red Hat licenses this file to you under the Apache License, version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*    http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.  See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.hornetq.api.core;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

import org.hornetq.core.client.HornetQClientLogger;


/**
* The configuration used to determine how the server will broadcast members.
* <p/>
* This is analogous to {@link org.hornetq.api.core.DiscoveryGroupConfiguration}
*
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a> Created 18 Nov 2008 08:44:30
*/
public final class UDPBroadcastGroupConfiguration implements BroadcastEndpointFactoryConfiguration, DiscoveryGroupConfigurationCompatibilityHelper
{
   private static final long serialVersionUID = 1052413739064253955L;

   private final transient String localBindAddress;

   private final transient int localBindPort;

   private final String groupAddress;

   private final int groupPort;

   public UDPBroadcastGroupConfiguration(final String groupAddress,
                                         final int groupPort,
                                         final String localBindAddress,
                                         final int localBindPort)
   {
      this.groupAddress = groupAddress;
      this.groupPort = groupPort;
      this.localBindAddress = localBindAddress;
      this.localBindPort = localBindPort;
   }

   public BroadcastEndpointFactory createBroadcastEndpointFactory()
   {
      return new BroadcastEndpointFactory()
      {
         @Override
         public BroadcastEndpoint createBroadcastEndpoint() throws Exception
         {
            return new UDPBroadcastEndpoint(groupAddress != null ? InetAddress.getByName(groupAddress) : null,
                                            groupPort,
                                            localBindAddress != null ? InetAddress.getByName(localBindAddress) : null,
                                            localBindPort);
         }
      };
   }

   public String getGroupAddress()
   {
      return groupAddress;
   }

   public int getGroupPort()
   {
      return groupPort;
   }

   public int getLocalBindPort()
   {
      return localBindPort;
   }

   public String getLocalBindAddress()
   {
      return localBindAddress;
   }

   /**
    * <p> This is the member discovery implementation using direct UDP. It was extracted as a refactoring from
    * {@link org.hornetq.core.cluster.DiscoveryGroup}</p>
    *
    * @author Tomohisa
    * @author Howard Gao
    * @author Clebert Suconic
    */
   private static class UDPBroadcastEndpoint implements BroadcastEndpoint
   {
      private static final int SOCKET_TIMEOUT = 500;

      private final InetAddress localAddress;

      private final int localBindPort;

      private final InetAddress groupAddress;

      private final int groupPort;

      private DatagramSocket broadcastingSocket;

      private MulticastSocket receivingSocket;

      private volatile boolean open;

      public UDPBroadcastEndpoint(final InetAddress groupAddress,
                                  final int groupPort,
                                  final InetAddress localBindAddress,
                                  final int localBindPort) throws UnknownHostException
      {
         this.groupAddress = groupAddress;
         this.groupPort = groupPort;
         this.localAddress = localBindAddress;
         this.localBindPort = localBindPort;
      }


      public void broadcast(byte[] data) throws Exception
      {
         DatagramPacket packet = new DatagramPacket(data, data.length, groupAddress, groupPort);
         broadcastingSocket.send(packet);
      }

      public byte[] receiveBroadcast() throws Exception
      {
         final byte[] data = new byte[65535];
         final DatagramPacket packet = new DatagramPacket(data, data.length);

         while (open)
         {
            try
            {
               receivingSocket.receive(packet);
            }
            // TODO: Do we need this?
            catch (InterruptedIOException e)
            {
               continue;
            }
            catch (IOException e)
            {
               if (open)
               {
                  HornetQClientLogger.LOGGER.warn(this + " getting exception when receiving broadcasting.", e);
               }
            }
            break;
         }
         return data;
      }

      public byte[] receiveBroadcast(long time, TimeUnit unit) throws Exception
      {
         // We just use the regular method on UDP, there's no timeout support
         // and this is basically for tests only
         return receiveBroadcast();
      }

      public void openBroadcaster() throws Exception
      {
         if (localBindPort != -1)
         {
            broadcastingSocket = new DatagramSocket(localBindPort, localAddress);
         }
         else
         {
            if (localAddress != null)
            {
               HornetQClientLogger.LOGGER.broadcastGroupBindError();
            }
            broadcastingSocket = new DatagramSocket();
         }

         open = true;
      }

      public void openClient() throws Exception
      {
         // HORNETQ-874
         if (checkForLinux() || checkForSolaris() || checkForHp())
         {
            try
            {
               receivingSocket = new MulticastSocket(new InetSocketAddress(groupAddress, groupPort));
            }
            catch (IOException e)
            {
               HornetQClientLogger.LOGGER.ioDiscoveryError(groupAddress.getHostAddress(), groupAddress instanceof Inet4Address ? "IPv4" : "IPv6");

               receivingSocket = new MulticastSocket(groupPort);
            }
         }
         else
         {
            receivingSocket = new MulticastSocket(groupPort);
         }

         if (localAddress != null)
         {
            receivingSocket.setInterface(localAddress);
         }

         receivingSocket.joinGroup(groupAddress);

         receivingSocket.setSoTimeout(SOCKET_TIMEOUT);

         open = true;
      }

      //@Todo: using isBroadcast to share endpoint between broadcast and receiving
      public void close(boolean isBroadcast) throws Exception
      {
         open = false;

         if (broadcastingSocket != null)
         {
            broadcastingSocket.close();
         }

         if (receivingSocket != null)
         {
            receivingSocket.close();
         }
      }

      private static boolean checkForLinux()
      {
         return checkForPresence("os.name", "linux");
      }

      private static boolean checkForHp()
      {
         return checkForPresence("os.name", "hp");
      }

      private static boolean checkForSolaris()
      {
         return checkForPresence("os.name", "sun");
      }

      private static boolean checkForPresence(String key, String value)
      {
         try
         {
            String tmp = System.getProperty(key);
            return tmp != null && tmp.trim().toLowerCase().startsWith(value);
         }
         catch (Throwable t)
         {
            return false;
         }
      }

   }

   @Override
   public int hashCode()
   {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((groupAddress == null) ? 0 : groupAddress.hashCode());
      result = prime * result + groupPort;
      return result;
   }

   @Override
   public boolean equals(Object obj)
   {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      UDPBroadcastGroupConfiguration other = (UDPBroadcastGroupConfiguration) obj;
      if (groupAddress == null)
      {
         if (other.groupAddress != null)
            return false;
      }
      else if (!groupAddress.equals(other.groupAddress))
         return false;
      if (groupPort != other.groupPort)
         return false;
      return true;
   }
}
TOP

Related Classes of org.hornetq.api.core.UDPBroadcastGroupConfiguration$UDPBroadcastEndpoint

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.