Package com.opengamma.core.change

Source Code of com.opengamma.core.change.JmsChangeManager

/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.core.change;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.Topic;

import org.fudgemsg.FudgeContext;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.FudgeMsgEnvelope;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.Lifecycle;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.transport.ByteArrayFudgeMessageReceiver;
import com.opengamma.transport.FudgeMessageReceiver;
import com.opengamma.transport.jms.JmsByteArrayMessageDispatcher;
import com.opengamma.transport.jms.JmsByteArrayMessageSender;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.PublicSPI;
import com.opengamma.util.fudgemsg.OpenGammaFudgeContext;
import com.opengamma.util.jms.JmsConnector;

/**
* Manager for receiving and handling entity change events.
* <p>
* Events are sent when an entity is added, updated, removed or corrected.
* <p>
* This class is mutable and thread-safe using concurrent collections.
*/
@PublicSPI
public class JmsChangeManager extends BasicChangeManager implements MessageListener, FudgeMessageReceiver, Lifecycle {

  /** Logger. */
  private static final Logger s_logger = LoggerFactory.getLogger(JmsChangeManager.class);

  /**
   * The JMS connector, not null
   */
  private final JmsConnector _jmsConnector;
  /**
   * The JMS message dispatcher.
   */
  private final JmsByteArrayMessageDispatcher _messageDispatcher;
  /**
   * The connection.
   */
  private volatile Connection _connection;

  /**
   * Creates a change manager.
   * <p>
   * The topic name will be defaulted to the name of this class if not set.
   *
   * @param connector  the JMS connector, not null
   */
  public JmsChangeManager(JmsConnector connector) {
    ArgumentChecker.notNull(connector, "connector");
    _jmsConnector = connector.ensureTopicName();
    ByteArrayFudgeMessageReceiver bafmr = new ByteArrayFudgeMessageReceiver(this, OpenGammaFudgeContext.getInstance());
    _messageDispatcher = new JmsByteArrayMessageDispatcher(bafmr);
  }

  /**
   * Creates a change manager.
   *
   * @param connector  the JMS connector, not null
   * @param topicName  the topic name to use, not null
   */
  public JmsChangeManager(JmsConnector connector, String topicName) {
    ArgumentChecker.notNull(connector, "connector");
    _jmsConnector = connector.withTopicName(topicName);
    ByteArrayFudgeMessageReceiver bafmr = new ByteArrayFudgeMessageReceiver(this, OpenGammaFudgeContext.getInstance());
    _messageDispatcher = new JmsByteArrayMessageDispatcher(bafmr);
  }

  //-------------------------------------------------------------------------
  @Override
  public void start() {
    final String topicName = _jmsConnector.getTopicName();
    try {
      _connection = _jmsConnector.getConnectionFactory().createConnection();
      _connection.start();
      final Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      final Topic topic = session.createTopic(topicName);
      final MessageConsumer messageConsumer = session.createConsumer(topic);
      messageConsumer.setMessageListener(this);
     
    } catch (JMSException ex) {
      throw new OpenGammaRuntimeException("Failed to create change manager on topic: " + topicName, ex);     
    }
  }

  @Override
  public void stop() {
    final String topicName = _jmsConnector.getTopicName();
    try {
      _connection.close();
      _connection = null;
     
    } catch (JMSException ex) {
      throw new OpenGammaRuntimeException("Failed to stop change manager on topic: " + topicName, ex);
    }
  }

  @Override
  public boolean isRunning() {
    return _connection != null;
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the JMS connector.
   *
   * @return the JMS connector, not null
   */
  public JmsConnector getJmsConnector() {
    return _jmsConnector;
  }

  //-------------------------------------------------------------------------
  /**
   * Handles an event when an entity changes.
   * <p>
   * This implementation sends the event by JMS to be received by all change
   * managers, including this one.
   *
   * @param event  the event that occurred, not null
   */
  @Override
  protected void handleEntityChanged(final ChangeEvent event) {
    final FudgeMsgEnvelope msg = OpenGammaFudgeContext.getInstance().toFudgeMsg(event);
    s_logger.debug("Sending change message {}", msg);
    final byte[] fudgeMsg = OpenGammaFudgeContext.getInstance().toByteArray(msg.getMessage());
    final JmsByteArrayMessageSender messageSender = new JmsByteArrayMessageSender(getJmsConnector().getTopicName(), getJmsConnector().getJmsTemplateTopic());
    messageSender.send(fudgeMsg);
  }

  @Override
  public void onMessage(Message message) {
    try {
      _messageDispatcher.onMessage(message);
    } catch (Exception e) {
      // NOTE jonathan 2013-06-05 -- it's an error to throw an exception in onMessage and may cause messages to back up
      // in the JMS broker which could affect its stability. Drop the message.
      s_logger.error("Error processing JMS message", e);
    }
  }

  @Override
  public void messageReceived(FudgeContext fudgeContext, FudgeMsgEnvelope msgEnvelope) {
    final FudgeMsg msg = msgEnvelope.getMessage();
    s_logger.debug("Received change message {}", msg);
    final FudgeDeserializer deserializer = new FudgeDeserializer(fudgeContext);
    final ChangeEvent event = deserializer.fudgeMsgToObject(ChangeEvent.class, msg);
    fireEntityChanged(event);
  }

  //-------------------------------------------------------------------------
  /**
   * Returns a debugging string for the manager.
   *
   * @return the debugging string, not null
   */
  @Override
  public String toString() {
    return getClass().getSimpleName();
  }

}
TOP

Related Classes of com.opengamma.core.change.JmsChangeManager

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.