View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements. See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache license, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License. You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the license for the specific language governing permissions and
    15   * limitations under the license.
    16   */
    17
    18  package org.apache.logging.log4j.core.appender.mom;
    19
    20  import java.io.Serializable;
    21  import javax.jms.Connection;
    22  import javax.jms.ConnectionFactory;
    23  import javax.jms.Destination;
    24  import javax.jms.JMSException;
    25  import javax.jms.Message;
    26  import javax.jms.MessageConsumer;
    27  import javax.jms.MessageProducer;
    28  import javax.jms.Session;
    29  import javax.naming.NamingException;
    30
    31  import org.apache.logging.log4j.Logger;
    32  import org.apache.logging.log4j.core.appender.AbstractManager;
    33  import org.apache.logging.log4j.core.appender.ManagerFactory;
    34  import org.apache.logging.log4j.core.net.JndiManager;
    35  import org.apache.logging.log4j.status.StatusLogger;
    36
    37  /**
    38   * JMS connection and session manager. Can be used to access MessageProducer, MessageConsumer, and Message objects
    39   * involving a configured ConnectionFactory and Destination.
    40   */
    41  public class JmsManager extends AbstractManager {
    42
    43      private static final Logger LOGGER = StatusLogger.getLogger();
    44
    45      private static final JmsManagerFactory FACTORY = new JmsManagerFactory();
    46
    47      private final JndiManager jndiManager;
    48      private final Connection connection;
    49      private final Session session;
    50      private final Destination destination;
    51
    52      private JmsManager(final String name, final JndiManager jndiManager, final String connectionFactoryName,
    53                         final String destinationName, final String username, final String password)
    54          throws NamingException, JMSException {
    55          super(name);
    56          this.jndiManager = jndiManager;
    57          final ConnectionFactory connectionFactory = this.jndiManager.lookup(connectionFactoryName);
    58          if (username != null && password != null) {
    59              this.connection = connectionFactory.createConnection(username, password);
    60          } else {
    61              this.connection = connectionFactory.createConnection();
    62          }
    63          this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    64          this.destination = this.jndiManager.lookup(destinationName);
    65          this.connection.start();
    66      }
    67
    68      /**
    69       * Gets a JmsManager using the specified configuration parameters.
    70       *
    71       * @param name                  The name to use for this JmsManager.
    72       * @param jndiManager           The JndiManager to look up JMS information through.
    73       * @param connectionFactoryName The binding name for the {@link javax.jms.ConnectionFactory}.
    74       * @param destinationName       The binding name for the {@link javax.jms.Destination}.
    75       * @param username              The username to connect with or {@code null} for no authentication.
    76       * @param password              The password to use with the given username or {@code null} for no authentication.
    77       * @return The JmsManager as configured.
    78       */
    79      public static JmsManager getJmsManager(final String name, final JndiManager jndiManager,
    80                                             final String connectionFactoryName, final String destinationName,
    81                                             final String username, final String password) {
    82          final JmsConfiguration configuration = new JmsConfiguration(jndiManager, connectionFactoryName, destinationName,
    83              username, password);
    84          return FACTORY.createManager(name, configuration);
    85      }
    86
    87      /**
    88       * Creates a MessageConsumer on this Destination using the current Session.
    89       *
    90       * @return A MessageConsumer on this Destination.
    91       * @throws JMSException
    92       */
    93      public MessageConsumer createMessageConsumer() throws JMSException {
    94          return this.session.createConsumer(this.destination);
    95      }
    96
    97      /**
    98       * Creates a MessageProducer on this Destination using the current Session.
    99       *
    100      * @return A MessageProducer on this Destination.
    101      * @throws JMSException
    102      */
    103     public MessageProducer createMessageProducer() throws JMSException {
    104         return this.session.createProducer(this.destination);
    105     }
    106
    107     /**
    108      * Creates a TextMessage or ObjectMessage from a Serializable object. For instance, when using a text-based
    109      * {@link org.apache.logging.log4j.core.Layout} such as {@link org.apache.logging.log4j.core.layout.PatternLayout},
    110      * the {@link org.apache.logging.log4j.core.LogEvent} message will be serialized to a String. When using a
    111      * layout such as {@link org.apache.logging.log4j.core.layout.SerializedLayout}, the LogEvent message will be
    112      * serialized as a Java object.
    113      *
    114      * @param object The LogEvent or String message to wrap.
    115      * @return A new JMS message containing the provided object.
    116      * @throws JMSException
    117      */
    118     public Message createMessage(final Serializable object) throws JMSException {
    119         if (object instanceof String) {
    120             return this.session.createTextMessage((String) object);
    121         }
    122         return this.session.createObjectMessage(object);
    123     }
    124
    125     @Override
    126     protected void releaseSub() {
    127         try {
    128             this.session.close();
    129         } catch (final JMSException ignored) {
    130         }
    131         try {
    132             this.connection.close();
    133         } catch (final JMSException ignored) {
    134         }
    135         this.jndiManager.release();
    136     }
    137
    138     private static class JmsConfiguration {
    139         private final JndiManager jndiManager;
    140         private final String connectionFactoryName;
    141         private final String destinationName;
    142         private final String username;
    143         private final String password;
    144
    145         private JmsConfiguration(final JndiManager jndiManager, final String connectionFactoryName, final String destinationName,
    146                                  final String username, final String password) {
    147             this.jndiManager = jndiManager;
    148             this.connectionFactoryName = connectionFactoryName;
    149             this.destinationName = destinationName;
    150             this.username = username;
    151             this.password = password;
    152         }
    153     }
    154
    155     private static class JmsManagerFactory implements ManagerFactory<JmsManager, JmsConfiguration> {
    156
    157         @Override
    158         public JmsManager createManager(final String name, final JmsConfiguration data) {
    159             try {
    160                 return new JmsManager(name, data.jndiManager, data.connectionFactoryName, data.destinationName,
    161                     data.username, data.password);
    162             } catch (final Exception e) {
    163                 LOGGER.error("Error creating JmsManager using ConnectionFactory [{}] and Destination [{}].",
    164                     data.connectionFactoryName, data.destinationName, e);
    165                 return null;
    166             }
    167         }
    168     }
    169
    170 }