Package org.geoserver.cluster.impl

Source Code of org.geoserver.cluster.impl.JMSActiveMQFactory

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.cluster.impl;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
import java.util.logging.Level;

import javax.annotation.PostConstruct;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.Topic;

import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.pool.PooledConnectionFactory;
import org.geoserver.cluster.JMSFactory;
import org.geoserver.cluster.configuration.BrokerConfiguration;
import org.geoserver.cluster.configuration.ConnectionConfiguration;
import org.geoserver.cluster.configuration.EmbeddedBrokerConfiguration;
import org.geoserver.cluster.configuration.JMSConfiguration;
import org.geoserver.cluster.configuration.TopicConfiguration;
import org.geoserver.cluster.configuration.ConnectionConfiguration.ConnectionConfigurationStatus;
import org.geotools.util.logging.Logging;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

/**
*
* @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it
*
*/
public class JMSActiveMQFactory extends JMSFactory implements InitializingBean {

  private final static java.util.logging.Logger LOGGER = Logging
      .getLogger(JMSActiveMQFactory.class);

  @Autowired
  private JMSConfiguration config;

  @Autowired
  private JMSXBeanBrokerFactory bf;

  // used to track changes to the configuration
  private String brokerURI;

  private String topicName;

  private PooledConnectionFactory cf;

  private Topic topic;

  // times to test (connection)
  private static int max;

  // millisecs to wait between tests (connection)
  private static long maxWait;

  // embedded brokerURI
  private BrokerService brokerService;

  private String brokerName;

  @Override
  public void afterPropertiesSet() throws Exception {

    // TODO initialize connections in order (first broker, then client)

  }

  // <bean id="JMSClientDestination"
  // class="org.apache.activemq.command.ActiveMQQueue">
  // <value="Consumer.${instance.name}.VirtualTopic.${topic.name}" />
  // </bean>
  @Override
  public Destination getClientDestination(Properties configuration) {
    StringBuilder builder = new StringBuilder("Consumer.");
    String instanceName = configuration
        .getProperty(JMSConfiguration.INSTANCE_NAME_KEY);
    String topicName = configuration
        .getProperty(TopicConfiguration.TOPIC_NAME_KEY);
    return new org.apache.activemq.command.ActiveMQQueue(builder
        .append(instanceName).append(".").append(topicName).toString());
  }

  // <!-- DESTINATION -->
  // <!-- A Destination in ActiveMQ -->
  // <bean id="JMSServerDestination"
  // class="org.apache.activemq.command.ActiveMQTopic">
  // <!-- <constructor-arg value="VirtualTopic.${topic.name}" /> -->
  // <constructor-arg value="VirtualTopic.>" />
  // </bean>
  @Override
  public Topic getTopic(Properties configuration) {
    // TODO move me to implementation jmsFactory implementation
    // if topicName is changed
    final String topicConfiguredName = configuration
        .getProperty(TopicConfiguration.TOPIC_NAME_KEY);
    if (topic == null || topicName.equals(topicConfiguredName)) {
      topicName = topicConfiguredName;
      topic = new org.apache.activemq.command.ActiveMQTopic(
          configuration
              .getProperty(TopicConfiguration.TOPIC_NAME_KEY));
    }
    if (topic == null) {
      throw new IllegalStateException(
          "Unable to load a JMS Topic destination");
    }
    return topic;
  }

  // <!-- A connection to ActiveMQ -->
  @Override
  public ConnectionFactory getConnectionFactory(Properties configuration) {
    final String _brokerURI = config
        .getConfiguration(BrokerConfiguration.BROKER_URL_KEY);
    final boolean changed = checkBrokerURI(_brokerURI);
    if (LOGGER.isLoggable(Level.INFO)) {
      LOGGER.info("Using brokerURI: " + brokerURI);
    }
   
    if (cf == null) {
      // need to be initialized
      cf = new PooledConnectionFactory(brokerURI);

    } else {
        if (changed) {
      // clear pending connections
      try {
        destroyConnectionFactory();
      } catch (Exception e) {
        // eat
      }
      // create a new connection
      cf = new PooledConnectionFactory(brokerURI);
      // cf.start();
        }

                }
    return cf;
  }

  /**
   * @return true if brokerURI is modified
   */
  private boolean checkBrokerURI(final String _brokerURI) {
    if (brokerURI == null) {
      if (_brokerURI == null || _brokerURI.length() == 0) {
        brokerURI = getDefaultURI();
        return true;
      } else {
        // initialize to the new configuration
        brokerURI = _brokerURI;

        // check the URI syntax
        try {
          new URI(brokerURI);
        } catch (URISyntaxException e) {
          if (LOGGER.isLoggable(Level.SEVERE)) {
            LOGGER.severe(e.getLocalizedMessage());
          }
          brokerURI = getDefaultURI();
        }
        return true;
      }
    } else {
      if (_brokerURI == null || _brokerURI.length() == 0) {
        // use the default
        return checkBrokerURI(getDefaultURI());
       
      } else if (brokerURI.equalsIgnoreCase(_brokerURI)) {
        return false;
      } else {
        // something is changed: reset
        brokerURI = null;
        return checkBrokerURI(_brokerURI);
      }
    }
  }

  private String getDefaultURI() {
    // default brokerURI
    return "vm://"
        + config.getConfiguration(JMSConfiguration.INSTANCE_NAME_KEY)
        + "?create=false&waitForStart=5000";
  }

  private void destroyConnectionFactory(){
    if (cf != null) {
      // close all the connections
      cf.clear();
      // stop the factory
      cf.stop();
      // set null
      cf = null;
    }
  }
 
  private void destroyBrokerService() throws Exception{
    if (brokerService != null) {
      brokerService.stop();
    }
  }
 
  @Override
  public void destroy() throws Exception {
    destroyConnectionFactory();
    destroyBrokerService();
  }

  @Override
  public boolean startEmbeddedBroker(final Properties configuration)
      throws Exception {
    if (LOGGER.isLoggable(Level.INFO)) {
      LOGGER.info("Starting the embedded brokerURI");
    }
    if (brokerService == null) {
      final String xBeanBroker = configuration
          .getProperty(ActiveMQEmbeddedBrokerConfiguration.BROKER_URL_KEY);
      // final XBeanBrokerFactory bf = new XBeanBrokerFactory();
      brokerService = bf.createBroker(new URI(xBeanBroker));
      brokerService.setEnableStatistics(false);

      // override the name of the brokerURI using the instance name which
      // should be unique within the network
      brokerName = configuration.getProperty(JMSConfiguration.INSTANCE_NAME_KEY);
      brokerService.setBrokerName(brokerName);
      brokerService.setUseLocalHostBrokerName(false);
      brokerService.setVmConnectorURI(new URI("vm://"+brokerName));
    } else {
      if (LOGGER.isLoggable(Level.WARNING)) {
        LOGGER.warning("The embedded brokerURI service already exists, probably it is already started");
      }
      if (brokerService.isStarted()) {
        if (LOGGER.isLoggable(Level.WARNING)) {
          LOGGER.warning("SKIPPING: The embedded brokerURI is already started");
        }
        return true;
      }
    }
    if (!brokerService.isStarted()) {
      brokerService.start();
    }
    for (int i = -1; i < max; ++i) {
      try {
        if (brokerService.isStarted()) {
          if (LOGGER.isLoggable(Level.INFO)) {
            LOGGER.info("Embedded brokerURI is now started");
          }
          return true;
        }
        Thread.sleep(maxWait);
      } catch (Exception e1) {
        if (LOGGER.isLoggable(Level.SEVERE)) {
          LOGGER.severe("Unable to start the embedded brokerURI"
              + e1.getLocalizedMessage());
        }
        return false;
      }
    }
    if (LOGGER.isLoggable(Level.SEVERE)) {
      LOGGER.severe("Unable to start the embedded brokerURI");
    }
    return false;
  }

  @Override
  public boolean isEmbeddedBrokerStarted() {
    return brokerService == null ? false : brokerService.isStarted();
  }

  @Override
  public boolean stopEmbeddedBroker() throws Exception {
    if (LOGGER.isLoggable(Level.INFO)) {
      LOGGER.info("Embedded brokerURI is now stopped");
    }
    if (brokerService == null) {
      return true;
    }
    brokerService.stop();
    for (int i = -1; i < max; ++i) {
      try {
        if (!brokerService.isStarted()) {
          if (LOGGER.isLoggable(Level.INFO)) {
            LOGGER.info("Embedded brokerURI is now stopped");
          }
          brokerService = null;
          return true;
        }
        if (LOGGER.isLoggable(Level.INFO)) {
          LOGGER.info("Embedded brokerURI is going to stop: waiting...");
        }
        Thread.sleep(maxWait);
      } catch (Exception e1) {
        if (LOGGER.isLoggable(Level.SEVERE)) {
          LOGGER.severe("Unable to start the embedded brokerURI"
              + e1.getLocalizedMessage());
        }
        return false;
      }
    }
    if (LOGGER.isLoggable(Level.SEVERE)) {
      LOGGER.severe("Unable to stop the embedded brokerURI");
    }
    return false;
  }

  @PostConstruct
  private void init() {
    // // times to test (connection)
    max = Integer.parseInt(config.getConfiguration(
        ConnectionConfiguration.CONNECTION_RETRY_KEY).toString());
    // millisecs to wait between tests (connection)
    maxWait = Long.parseLong(config.getConfiguration(
        ConnectionConfiguration.CONNECTION_MAXWAIT_KEY).toString());

    // check configuration for connection and try to start if needed
    if (EmbeddedBrokerConfiguration.isEnabled(config)) {
      if (!isEmbeddedBrokerStarted()) {
        try {
          if (!startEmbeddedBroker(config.getConfigurations())) {
            if (LOGGER.isLoggable(Level.SEVERE)) {
              LOGGER.severe("Unable to start the embedded brokerURI, force status to disabled");
            }

            // change configuration status
            config.putConfiguration(
                ConnectionConfiguration.CONNECTION_KEY,
                ConnectionConfigurationStatus.disabled
                    .toString());

          } else {
            if (LOGGER.isLoggable(Level.SEVERE)) {
              LOGGER.severe("Started the embedded brokerURI: "
                  + brokerService.toString());
            }
          }
        } catch (Exception e) {
          LOGGER.log(Level.SEVERE, e.getMessage(), e);
          // change configuration status
          config.putConfiguration(
              ConnectionConfiguration.CONNECTION_KEY,
              ConnectionConfigurationStatus.disabled.toString());
        }
        // store changes to the configuration
        try {
          config.storeConfig();
        } catch (IOException e) {
          LOGGER.log(Level.SEVERE, e.getMessage(), e);
        }
      } else {
        if (LOGGER.isLoggable(Level.WARNING)) {
          LOGGER.warning("The brokerURI seems to be already started");
        }
      }
    }
  }

}
TOP

Related Classes of org.geoserver.cluster.impl.JMSActiveMQFactory

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.