All Downloads are FREE. Search and download functionalities are using the official Maven repository.

forklift.producers.ActiveMQProducer Maven / Gradle / Ivy

There is a newer version: 3.8
Show newest version
package forklift.producers;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.base.Strings;

import forklift.connectors.ForkliftMessage;
import forklift.message.ActiveMQHeaders;
import forklift.message.Header;

import org.apache.activemq.command.ActiveMQMessage;

import java.lang.StringBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;

public class ActiveMQProducer implements ForkliftProducerI {

    private static final ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule())
                                                                 .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    private MessageProducer producer;
    private Destination destination;
    private Map headers;
    private Map properties;
    private Session session;

    public ActiveMQProducer(MessageProducer producer, Session session) {
        this.producer = producer;
        this.session = session;
    }

    @Override
    /**
    * Send in a string and the producer generate a ForkliftMessage with it
    * @param message - String representation of the message/data that needs to be sent
    * @return String - JMSCorrelationID
    **/
    public String send(String message) throws ProducerException {
        try {
            return send(new ForkliftMessage(message));
        } catch (Exception e) {
            throw new ProducerException("Failed to send message", e);
        }
    }

    @Override
    /**
    * Send in an object and the producer will marshall it into a ForkliftMessage
    * @param message - Object representation of the message/data that needs to be sent
    * @return String - JMSCorrelationID
    **/
    public String send(Object message) throws ProducerException {
        try {
            return send(new ForkliftMessage(mapper.writeValueAsString(message)));
        } catch (Exception e) {
            throw new ProducerException("Failed to send message", e);
        }
    }

    @Override
    /**
    * Send in a map and the producer will convert it to a key-value pair before sending a ForkliftMessage
    * @param message - Map of the message/data that needs to be sent
    * @return String - JMSCorrelationID
    **/
    public String send(Map message) throws ProducerException {
        final StringBuilder output = new StringBuilder();
        message.forEach((k, v) -> output.append(k).append('=').append(v).append('\n'));
        return send(new ForkliftMessage(output.toString()));
    }

    @Override
    /**
    * Send a ForkliftMessage.
    * @param message - ForkliftMessage
    * @return String - JMSCorrelationID
    **/
    public String send(ForkliftMessage message) throws ProducerException {
        try {
            Message msg = prepAndValidate(message);
            if (msg != null) {
                producer.send(msg);
                return msg.getJMSCorrelationID();
            } else {
                throw new ProducerException("Forklift MSG is null");
            }
        } catch (Exception e) {
            throw new ProducerException("Failed to send message", e);
        }
    }

    @Override
    /**
    * Send in an object and the producer will marshall it into a ForkliftMessage
    * @param properties - message properties
    * @param message - ForkliftMessage
    * @return String - JMSCorrelationID
    **/
    public String send(Map properties,
                       ForkliftMessage message) throws ProducerException {
        Message msg = prepAndValidate(message, null, properties);
        try {
            producer.send(msg);
            return msg.getJMSCorrelationID();
        } catch (Exception e) {
            throw new ProducerException("Failed to send message", e);
        }
    }

    @Override
    /**
    * Send in an object and the producer will marshall it into a ForkliftMessage
    * @param headers - message headers
    * @param properties - message properties
    * @param message - ForkliftMessage
    * @return String - JMSCorrelationID
    **/
    public String send(Map headers, 
                       Map properties,
                       ForkliftMessage message) throws ProducerException {
        Message msg = prepAndValidate(message, headers, properties);
        try {
            producer.send(msg);
            return msg.getJMSCorrelationID();
        } catch (Exception e) {
            throw new ProducerException("Failed to send message", e);
        }
    }

    /**
    * validate message and prepare for sending.
    * @param message - ForkliftMessage to be checked
    * @return - jms message ready to be sent to endpoint
    **/
    private Message prepAndValidate(ForkliftMessage message) throws ProducerException {
        Message msg = forkliftToJms(message);
        // check the ID
        try {
            if (Strings.isNullOrEmpty(msg.getJMSCorrelationID())) {
                msg.setJMSCorrelationID(UUID.randomUUID().toString().replaceAll("-", ""));
            }
        } catch (Exception e) {
            throw new ProducerException("Failed to set setJMSCorrelationID");
        }

        try {
            if(this.headers != null) {
                setMessageHeaders(msg, this.headers);
            }

            if(this.properties != null) {
                setMessageProperties(msg, this.properties);
            }
        } catch (Exception e) {
            throw new ProducerException("Exception while setting message properties/headers with producer properties/headers", e);
        }
        return msg;
    }

    /**
    * validate message and prepare for sending.
    * @param message - ForkliftMessage to be checked
    * @param headers - ActiveMQHeaders message headers to be set
    * @param properties - message properties to be set
    * @return - jms message ready to be sent to endpoint
    **/
    private Message prepAndValidate(ForkliftMessage message,
                                    Map headers,
                                    Map properties) throws ProducerException {
        Message msg = forkliftToJms(message);
        try {
            if (Strings.isNullOrEmpty(msg.getJMSCorrelationID())) {
                msg.setJMSCorrelationID(UUID.randomUUID().toString().replaceAll("-", ""));
            }
        } catch (Exception e) {
            throw new ProducerException("Failed to set setJMSCorrelationID");
        }
        try {
            setMessageHeaders(msg, headers);
        } catch (Exception e) {
            throw new ProducerException("Failed to set message header", e);
        }
        try {
            setMessageProperties(msg, properties);
        } catch (Exception e) {
            throw new ProducerException("Failed to set message property", e);
        }

        return msg;
    }

    /**
    * Generate javax.jms.Message from a Forklift Message
    * @param message - Forklift message to be converted
    * @return - a new javax.jms.Message
    **/
    private Message forkliftToJms(ForkliftMessage message) throws ProducerException {

        try {
            final Message msg = session.createTextMessage(message.getMsg());

            // Set the jms correlation id.
            if (message.getId() != null && !message.getId().trim().isEmpty())
                msg.setJMSCorrelationID(message.getId());

            setMessageHeaders(msg, message.getHeaders());
            setMessageProperties(msg, message.getProperties());
            return msg;
        } catch (Exception e) {
            throw new ProducerException("Error creating JMS Message", e);
        }
    }

    private void setMessageHeaders(Message msg, Map headers) throws ProducerException {
        if (msg != null && headers != null) {
            headers.entrySet().stream().filter(entry -> entry.getValue() != null)
                .forEach(entry -> {
                    if (ActiveMQHeaders.getFunctions().get(entry.getKey()).get((ActiveMQMessage)msg) == null) {
                        ActiveMQHeaders.getFunctions().get(entry.getKey()).set((ActiveMQMessage)msg,entry.getValue());
                    }
            });
        }
    }

    private void setMessageProperties(Message msg, Map properties) throws ProducerException {
        if (msg != null && properties != null) {
            final Map props = new HashMap<>();
            if (this.properties != null)
                props.putAll(this.properties);
            if (properties != null)
                props.putAll(properties);

            props.entrySet().stream().filter(entry -> entry.getValue() != null)
                .forEach(property -> {
                    try {
                        if (msg.getObjectProperty(property.getKey()) == null) {
                            msg.setObjectProperty(property.getKey(), property.getValue());
                        }
                    } catch (Exception e) {
                        //Catch it but just move on.
                    }
                });
        }
    }

    public int getDeliveryMode() throws ProducerException {
        try {
            return this.producer.getDeliveryMode();
        } catch (Exception e) {
            throw new ProducerException("Failed to get DelieveryMode");
        }
    }

    public void setDeliveryMode(int mode) throws ProducerException {
        try {
            this.producer.setDeliveryMode(mode);
        } catch (Exception e) {
            throw new ProducerException("Failed to set DelieveryMode");
        }
    }

    public long getTimeToLive() throws ProducerException {
        try {
            return this.producer.getTimeToLive();
        } catch (Exception e) {
            throw new ProducerException("Failed to get TimeToLive");
        }
    }

    public void setTimeToLive(long timeToLive) throws ProducerException {
        try {
            this.producer.setTimeToLive(timeToLive);
        } catch (Exception e) {
            throw new ProducerException("Failed to set TimeToLive");
        }
    }

    @Override
    public Map getHeaders() throws ProducerException {
        try {
            return this.headers;
        } catch (Exception e) {
            throw new ProducerException("Failed to get headers");
        }

    }

    @Override
    public void setHeaders(Map headers) throws ProducerException {
        try {
            this.headers = headers;
        } catch (Exception e) {
            throw new ProducerException("Failed to set headers");
        }
    }

    @Override
    public Map getProperties() throws ProducerException {
        try {
            return this.properties;
        } catch (Exception e) {
            throw new ProducerException("Failed to get properties");
        }
    }

    @Override
    public void setProperties(Map properties) throws ProducerException {
        try {
            this.properties = properties;
        } catch (Exception e) {
            throw new ProducerException("Failed to set properties");
        }
    }

    @Override
    public void close() throws java.io.IOException {
        try {
            if (producer != null)
                producer.close();

            if (session != null)
                session.close();
        } catch (javax.jms.JMSException e) {
            throw new java.io.IOException("Failed to close MessageProducer", e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy