org.artificer.events.jms.JMSEventProducer.java Source code

Java tutorial

Introduction

Here is the source code for org.artificer.events.jms.JMSEventProducer.java

Source

/*
 * Copyright 2014 JBoss Inc
 *
 * 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.
 */
package org.artificer.events.jms;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.artificer.common.ArtificerConfig;
import org.artificer.common.ArtificerConstants;
import org.artificer.common.ontology.ArtificerOntology;
import org.artificer.events.ArtifactUpdateEvent;
import org.artificer.events.EventProducer;
import org.artificer.events.OntologyUpdateEvent;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.BaseArtifactType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.ArrayList;
import java.util.List;

/**
 * Provides a JMS implementation of the {@link EventProducer}.
 *
 * During {@link #startup()}, we check for the existence of a JMS
 * "ConnectionFactory" and any configured topics/queues, both through JNDI
 * names. If they exist, it means we're in a JavaEE environment and things are
 * correctly configured. We simply use the existing JMS framework and the
 * pre-existing topics/queues.
 *
 * @author Brett Meyer
 */
public class JMSEventProducer implements EventProducer {

    public static final String JMS_TYPE_ARTIFACT_CREATED = "artificer:artifactCreated";
    public static final String JMS_TYPE_ARTIFACT_UPDATED = "artificer:artifactUpdated";
    public static final String JMS_TYPE_ARTIFACT_DELETED = "artificer:artifactDeleted";
    public static final String JMS_TYPE_ONTOLOGY_CREATED = "artificer:ontologyCreated";
    public static final String JMS_TYPE_ONTOLOGY_UPDATED = "artificer:ontologyUpdated";
    public static final String JMS_TYPE_ONTOLOGY_DELETED = "artificer:ontologyDeleted";

    private static Logger LOG = LoggerFactory.getLogger(JMSEventProducer.class);

    private Connection connection = null;

    private Session session = null;

    private final List<Destination> destinations = new ArrayList<Destination>();

    @Override
    public void startup() {
        if (ArtificerConfig.isJmsEnabled()) {
            try {
                String connectionFactoryName = ArtificerConfig.getConfigProperty(
                        ArtificerConstants.ARTIFICER_CONFIG_EVENT_JMS_CONNECTIONFACTORY, "ConnectionFactory");

                // Note that both properties end up doing the same thing.  Technically, we could combine both into one
                // single sramp.config.events.jms.destinations, but leaving them split for readability.
                String topicNamesProp = ArtificerConfig
                        .getConfigProperty(ArtificerConstants.ARTIFICER_CONFIG_EVENT_JMS_TOPICS, "");
                String[] topicNames = new String[0];
                if (StringUtils.isNotEmpty(topicNamesProp)) {
                    topicNames = topicNamesProp.split(",");
                }
                String queueNamesProp = ArtificerConfig
                        .getConfigProperty(ArtificerConstants.ARTIFICER_CONFIG_EVENT_JMS_QUEUES, "");
                String[] queueNames = new String[0];
                if (StringUtils.isNotEmpty(queueNamesProp)) {
                    queueNames = queueNamesProp.split(",");
                }

                // See if a ConnectionFactory and Topic/Queue exists on JNDI.  If so, assume JMS is properly
                // setup in a Java EE container and use it.

                ConnectionFactory connectionFactory = (ConnectionFactory) jndiLookup(connectionFactoryName);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

                for (String topicName : topicNames) {
                    Topic topic = (Topic) jndiLookup(topicName);
                    destinations.add(topic);
                }

                for (String queueName : queueNames) {
                    Queue queue = (Queue) jndiLookup(queueName);
                    destinations.add(queue);
                }
            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
            }
        }
    }

    @Override
    public void artifactCreated(BaseArtifactType artifact) {
        if (ArtificerConfig.isJmsEnabled()) {
            publishEvent(artifact, JMS_TYPE_ARTIFACT_CREATED);
        }
    }

    @Override
    public void artifactUpdated(BaseArtifactType updatedArtifact, BaseArtifactType oldArtifact) {
        if (ArtificerConfig.isJmsEnabled()) {
            ArtifactUpdateEvent event = new ArtifactUpdateEvent(updatedArtifact, oldArtifact);
            publishEvent(event, JMS_TYPE_ARTIFACT_UPDATED);
        }
    }

    @Override
    public void artifactDeleted(BaseArtifactType artifact) {
        if (ArtificerConfig.isJmsEnabled()) {
            publishEvent(artifact, JMS_TYPE_ARTIFACT_DELETED);
        }
    }

    @Override
    public void ontologyCreated(ArtificerOntology ontology) {
        if (ArtificerConfig.isJmsEnabled()) {
            publishEvent(ontology, JMS_TYPE_ONTOLOGY_CREATED);
        }
    }

    @Override
    public void ontologyUpdated(ArtificerOntology updatedOntology, ArtificerOntology oldOntology) {
        if (ArtificerConfig.isJmsEnabled()) {
            OntologyUpdateEvent event = new OntologyUpdateEvent(updatedOntology, oldOntology);
            publishEvent(event, JMS_TYPE_ONTOLOGY_UPDATED);
        }
    }

    @Override
    public void ontologyDeleted(ArtificerOntology ontology) {
        if (ArtificerConfig.isJmsEnabled()) {
            publishEvent(ontology, JMS_TYPE_ONTOLOGY_DELETED);
        }
    }

    private void publishEvent(Object payload, String type) {
        for (Destination destination : destinations) {
            MessageProducer producer = null;
            try {
                producer = session.createProducer(destination);
                TextMessage textMessage = session.createTextMessage();
                textMessage.setJMSType(type);

                ObjectMapper mapper = new ObjectMapper();
                String text = mapper.writeValueAsString(payload);
                textMessage.setText(text);

                producer.send(textMessage);
            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
            } finally {
                if (producer != null) {
                    try {
                        producer.close();
                    } catch (Exception e) {
                    }
                }
            }
        }
    }

    private Object jndiLookup(String name) throws NamingException {
        Context initContext = new InitialContext();
        try {
            Context jndiContext = (Context) initContext.lookup("java:comp/env");
            return jndiContext.lookup(name);
        } catch (NamingException e) {
            // EAP (no namespace)
            Context jndiContext = (Context) initContext.lookup("java:");
            return jndiContext.lookup(name);
        }
    }

    @Override
    public void shutdown() {
        if (ArtificerConfig.isJmsEnabled()) {
            try {
                session.close();
            } catch (Exception e) {
            }
            try {
                connection.close();
            } catch (Exception e) {
            }
        }
    }
}