Package play.modules.rabbitmq

Source Code of play.modules.rabbitmq.RabbitMQPlugin

/**
* Copyright 2011 The Apache Software Foundation
*
* Licensed 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.
*
* @author Felipe Oliveira (http://mashup.fm)
*
*/
package play.modules.rabbitmq;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.commons.lang.StringUtils;

import play.Logger;
import play.Play;
import play.PlayPlugin;
import play.modules.rabbitmq.stats.StatsService;
import play.modules.rabbitmq.util.ExceptionUtil;
import play.modules.rabbitmq.util.MsgMapper;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Address;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
import java.util.ArrayList;
import java.util.List;

// TODO: Auto-generated Javadoc
/**
* The Class RabbitMQPlugin.
*/
public class RabbitMQPlugin extends PlayPlugin {

  /** The Constant factory. */
  public static final ConnectionFactory factory = new ConnectionFactory();
 
  /** The mapper. */
  private static MsgMapper mapper = null;
 
  /** The stats service. */
  private static StatsService statsService = new StatsService();
 
  /** The consumers running. */
  private static boolean consumersActive = true;

  /**
   * On application start.
   */
  @Override
  public void onApplicationStart() {
    // Parse rabbitMQ connection url if one exists
    if (Play.configuration.containsKey("rabbitmq.url")) {
      String rabbitmqUrl = Play.configuration.getProperty("rabbitmq.url");
      URI rabbitmqUri;
      try {
        rabbitmqUri = new URI(rabbitmqUrl);
      } catch (URISyntaxException e) {
        throw new RuntimeException("Unable to parse rabbitmq.url (" + rabbitmqUrl + ")", e);
      }
     
      Play.configuration.setProperty("rabbitmq.host", rabbitmqUri.getHost());
      Play.configuration.setProperty("rabbitmq.port", Integer.toString(rabbitmqUri.getPort()));
     
      if (rabbitmqUri.getPath().length() > 1) {
        Play.configuration.setProperty("rabbitmq.vhost", rabbitmqUri.getPath().substring(1));
      }
     
      if (rabbitmqUri.getUserInfo() != null) {
        String[] rabbitmqUserInfo = rabbitmqUri.getUserInfo().split(":");
        Play.configuration.setProperty("rabbitmq.username", rabbitmqUserInfo[0]);
        Play.configuration.setProperty("rabbitmq.password", rabbitmqUserInfo[1]);
      }
    }
   
    // Connection Factory
    factory.setUsername(getUserName());
    factory.setPassword(getPassword());
    factory.setVirtualHost(getVhost());
  }
 
  /**
   * Consumers running.
   *
   * @return true, if successful
   */
  public static boolean areConsumersActive() {
    return consumersActive;
  }
 
  /**
   * Consumers running.
   *
   * @param b the b
   */
  public static void consumersActive(boolean b) {
    consumersActive = b;
  }
 
  /**
   * Stats service.
   *
   * @return the stats service
   */
  public static StatsService statsService() {
    return statsService;
  }

  /**
   * Mapper.
   *
   * @return the msg mapper
   */
  public static MsgMapper mapper() {
    if ( mapper != null ) {
      return mapper;
    }
    String s = Play.configuration.getProperty("rabbitmq.msgmapper");
    if ((s != null) && StringUtils.isNotBlank(s)) {
      try {
        mapper = MsgMapper.Type.valueOf(s).get();
      } catch (Throwable t) {
        Logger.error(ExceptionUtil.getStackTrace(t));
        mapper = MsgMapper.Type.json.get();
      }
    } else {
      mapper = MsgMapper.Type.json.get();
    }
    Logger.info("RabbitMQ Message Mapper: %s", mapper);
    if ( mapper == null ) {
      throw new RuntimeException( "RabbitMQ Message Mapper is null! Config Parameter 'rabbitmq.msgmapper': " + s );
    }
    return mapper;
  }

  /**
   * Gets the task channel.
   *
   * @return the task channel
   */
  protected Channel createChannel() {
    Channel channel = null;

    int attempts = 0;
    while (true) {
      attempts++;
      Logger.info("Attempting to connect to queue: attempt " + attempts);
      try {
        Connection connection = this.getConnection();
        channel = connection.createChannel();
        break;

      } catch (IOException e) {
        Logger.error("Error creating RabbitMQ channel, retrying in 5 secs - Exception: %s", ExceptionUtil.getStackTrace(e));
        try {
          Thread.sleep(1000 * 5);
        } catch (InterruptedException ex) {
        }
      }
    }
    return channel;
  }

  /**
   * Creates the channel.
   *
   * @param queue
   *            the queue
   * @return the channel
   * @throws Exception
   *             the exception
   */
  public Channel createChannel(String queue, String routingKey) throws Exception {
    // Counter that keeps track of number of retries
    int attempts = 0;

    // Get Plugin
    RabbitMQPlugin plugin = Play.plugin(RabbitMQPlugin.class);

    // Create Channel
    Channel channel = this.createChannel();

    // Basic Qos
    if (RabbitMQPlugin.isBasicQos()) {
      int prefetchCount = 1;
      channel.basicQos(prefetchCount);
    }

    // Start Daemon
    while (true) {
      // Add to the number of retries
      attempts++;

      // Log Debug
      Logger.debug("Retry " + attempts);

      // Get Next Delivery Message
      try {
        // http://www.rabbitmq.com/api-guide.html
        // channel.exchangeDeclare(exchangeName, "direct", true);
        // String queueName = channel.queueDeclare().getQueue();
        // channel.queueBind(queueName, exchangeName, routingKey);
       
        channel.exchangeDeclare(queue, plugin.getExchangeType(), true);
        channel.queueDeclare(queue, plugin.isDurable(), false, false, null);
        channel.queueBind(queue, queue, routingKey);

        // Log Debug
        Logger.info("RabbitMQ Task Channel Available: " + channel);

        // Return Channel
        return channel;

      } catch (Throwable t) {
        // Log Debug
        Logger.error("Error establishing a connection to RabbitMQ, will keep retrying - Exception: %s", ExceptionUtil.getStackTrace(t));

        // Sleep a little while before retrying
        try {
          Thread.sleep(1000 * 10);
        } catch (InterruptedException ex) {
        }
      }
    }
  }

/**
   * Creates the channel for a subscriber to consume messages from an exchange
   * (Exchange is created.  Subscribers queue and binding by routing key are created)
   *
   * @param exchangeName
   *            the exchange name
   * @param queue
   *            the queue
   * @param routingKey
   *            the routing key
   * @return the channel
   * @throws Exception
   *             the exception
   */
  public Channel createSubscribersChannel(String exchangeName, String queue, String routingKey) throws Exception {
    // Counter that keeps track of number of retries
    int attempts = 0;

    // Get Plugin
    RabbitMQPlugin plugin = Play.plugin(RabbitMQPlugin.class);

    // Create Channel
    Channel channel = this.createChannel();

    // Basic Qos
    if (RabbitMQPlugin.isBasicQos()) {
      int prefetchCount = 1;
      channel.basicQos(prefetchCount);
    }

    // Start Daemon
    while (true) {
      // Add to the number of retries
      attempts++;

      // Log Debug
      Logger.debug("Retry " + attempts);

      // Get Next Delivery Message
      try {
        // http://www.rabbitmq.com/api-guide.html
        channel.exchangeDeclare(exchangeName, plugin.getExchangeType(), true);
        channel.queueDeclare(queue, plugin.isDurable(), false, false, null);
        channel.queueBind(queue, exchangeName, routingKey);

        // Log Debug
        Logger.info("RabbitMQ Task Channel Available: " + channel);

        // Return Channel
        return channel;

      } catch (Throwable t) {
        // Log Debug
        Logger.error("Error establishing a connection to RabbitMQ, will keep retrying - Exception: %s", ExceptionUtil.getStackTrace(t));

        // Sleep a little while before retrying
        try {
          Thread.sleep(1000 * 10);
        } catch (InterruptedException ex) {
        }
      }
    }
  }

  /**
   * Creates the channel to publish messages to an exchange
   * (Exchange is created.  Queue and bindings are NOT created)
   *
   * @param exchangeName
   *            the exchange name
   * @return the channel
   * @throws Exception
   *             the exception
   */
  public Channel createPublishersChannel(String exchangeName) throws Exception {
    // Counter that keeps track of number of retries
    int attempts = 0;

    // Get Plugin
    RabbitMQPlugin plugin = Play.plugin(RabbitMQPlugin.class);

    // Create Channel
    Channel channel = this.createChannel();

    // Basic Qos
    if (RabbitMQPlugin.isBasicQos()) {
      int prefetchCount = 1;
      channel.basicQos(prefetchCount);
    }

    // Start Daemon
    while (true) {
      // Add to the number of retries
      attempts++;

      // Log Debug
      Logger.debug("Retry " + attempts);

      // Get Next Delivery Message
      try {
        // http://www.rabbitmq.com/api-guide.html
        channel.exchangeDeclare(exchangeName, plugin.getExchangeType(), true);

        // Log Debug
        Logger.info("RabbitMQ Task Channel Available: " + channel);

        // Return Channel
        return channel;

      } catch (Throwable t) {
        // Log Debug
        Logger.error("Error establishing a connection to RabbitMQ, will keep retrying - Exception: %s", ExceptionUtil.getStackTrace(t));

        // Sleep a little while before retrying
        try {
          Thread.sleep(1000 * 10);
        } catch (InterruptedException ex) {
        }
      }
    }
  }
          
  /**
   * Gets the user name.
   *
   * @return the user name
   */
  public static String getUserName() {
    String s = Play.configuration.getProperty("rabbitmq.username");
    if (s == null) {
      return "guest";
    }
    return s;
  }

  /**
   * Gets the password.
   *
   * @return the password
   */
  public static String getPassword() {
    String s = Play.configuration.getProperty("rabbitmq.password");
    if (s == null) {
      return "guest";
    }
    return s;
  }

  /**
   * Checks if is auto ack.
   *
   * @return true, if is auto ack
   */
  public static boolean isAutoAck() {
    boolean autoAck = false;
    String s = Play.configuration.getProperty("rabbitmq.autoAck");
    if (s == null) {
      return autoAck;
    }
    return Boolean.parseBoolean(s);
  }

  /**
   * Checks if is basic qos.
   *
   * @return true, if is basic qos
   */
  public static boolean isBasicQos() {
    boolean basicQos = true;
    String s = Play.configuration.getProperty("rabbitmq.basicQos");
    if (s == null) {
      return basicQos;
    }
    return Boolean.parseBoolean(s);
  }

  /**
   * Retries.
   *
   * @return the int
   */
  public static int retries() {
    int defaultRetries = 5;
    try {
      return Integer.valueOf(Play.configuration.getProperty("rabbitmq.retries", String.valueOf(defaultRetries)));
    } catch (Throwable t) {
      Logger.error(ExceptionUtil.getStackTrace(t));
      return defaultRetries;
    }
  }

  /**
   * Checks if is durable.
   *
   * @return true, if is durable
   */
  public static boolean isDurable() {
    boolean durable = true;
    String s = Play.configuration.getProperty("rabbitmq.durable");
    if (s == null) {
      return durable;
    }
    return Boolean.parseBoolean(s);
  }

  /**
   * Gets the basic properties.
   *
   * @return the basic properties
   */
  public static BasicProperties getBasicProperties() {
    if (isDurable() == false) {
      return null;
    }
    BasicProperties b = MessageProperties.PERSISTENT_TEXT_PLAIN;
    return b;
  }

  /**
   * Gets the exchange type.
   *
   * @return the exchange type
   */
  public static String getExchangeType() {
    String s = Play.configuration.getProperty("rabbitmq.exchangeType");
    if (s == null) {
      return "direct";
    }
    return s;
  }

  /**
   * Gets the vhost.
   *
   * @return the vhost
   */
  public static String getVhost() {
    String s = Play.configuration.getProperty("rabbitmq.vhost");
    if (s == null) {
      return "/";
    }
    return s;
  }

        /**
         * Gets address using conf rabbitmq.seeds=host1[:port1];host2[:port2]...
         *
         * @return
         */
        public Address[] getAddress(String seeds) {
            List<Address> addresses = new ArrayList<>();
            if (seeds == null || seeds.isEmpty()) {
                addresses.add(new Address("localhost", 5672));
                return addresses.toArray(new Address[0]);
            }
            String[] stringArray = seeds.split("[;,\\s]");
            for (String s : stringArray) {
                String[] hostPort = s.split(":");
                if (0 == hostPort.length) {
                    continue;
                }
                String host = hostPort[0];
                int port = 5672;
                if (hostPort.length > 1) {
                    port = Integer.parseInt(hostPort[1]);
                }
                addresses.add(new Address(host, port));
            }
            return addresses.toArray(new Address[0]);
        }
       
  /**
   * Gets the connection.
   *
   * @return the connection
   * @throws IOException
   *             Signals that an I/O exception has occurred.
   */
        public Connection getConnection() throws IOException {
            String seeds = Play.configuration.getProperty("rabbitmq.seeds");
            return factory.newConnection(getAddress(seeds));
        }
}
TOP

Related Classes of play.modules.rabbitmq.RabbitMQPlugin

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.