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  package org.apache.logging.log4j.core.net;
18  
19  import org.apache.logging.log4j.core.appender.ManagerFactory;
20  
21  import javax.jms.JMSException;
22  import javax.jms.Queue;
23  import javax.jms.QueueConnection;
24  import javax.jms.QueueConnectionFactory;
25  import javax.jms.QueueSender;
26  import javax.jms.QueueSession;
27  import javax.jms.Session;
28  import javax.naming.Context;
29  import javax.naming.NamingException;
30  import java.io.Serializable;
31  
32  /**
33   * Manager for a JMS Queue.
34   */
35  public class JMSQueueManager extends AbstractJMSManager {
36  
37      private static final JMSQueueManagerFactory factory = new JMSQueueManagerFactory();
38  
39      private final QueueConnection queueConnection;
40      private final QueueSession queueSession;
41      private final QueueSender queueSender;
42  
43      /**
44       * The Constructor.
45       * @param name The unique name of the connection.
46       * @param conn The QueueConnection.
47       * @param sess The QueueSession.
48       * @param sender The QueueSender.
49       */
50      protected JMSQueueManager(String name, QueueConnection conn, QueueSession sess, QueueSender sender) {
51          super(name);
52          this.queueConnection = conn;
53          this.queueSession = sess;
54          this.queueSender = sender;
55      }
56  
57      /**
58       * Obtain a JMSQueueManager.
59       * @param factoryName The fully qualified class name of the InitialContextFactory.
60       * @param providerURL The URL of the provider to use.
61       * @param urlPkgPrefixes A colon-separated list of package prefixes for the class name of the factory class that
62       * will create a URL context factory
63       * @param securityPrincipalName The name of the identity of the Principal.
64       * @param securityCredentials The security credentials of the Principal.
65       * @param factoryBindingName The name to locate in the Context that provides the QueueConnectionFactory.
66       * @param queueBindingName The name to use to locate the Queue.
67       * @param userName The userid to use to create the Queue Connection.
68       * @param password The password to use to create the Queue Connection.
69       * @return The JMSQueueManager.
70       */
71      public static JMSQueueManager getJMSQueueManager(String factoryName, String providerURL, String urlPkgPrefixes,
72                                                       String securityPrincipalName, String securityCredentials,
73                                                       String factoryBindingName, String queueBindingName,
74                                                       String userName, String password) {
75  
76          if (factoryBindingName == null) {
77              LOGGER.error("No factory name provided for JMSQueueManager");
78              return null;
79          }
80          if (queueBindingName == null) {
81              LOGGER.error("No topic name provided for JMSQueueManager");
82              return null;
83          }
84  
85          String name = "JMSQueue:" + factoryBindingName + '.' + queueBindingName;
86          return getManager(name, factory, new FactoryData(factoryName, providerURL, urlPkgPrefixes,
87              securityPrincipalName, securityCredentials, factoryBindingName, queueBindingName, userName, password));
88      }
89  
90      @Override
91      public void send(Serializable object) throws Exception {
92          super.send(object, queueSession, queueSender);
93      }
94  
95      @Override
96      public void releaseSub() {
97          try {
98              if (queueSession != null) {
99                  queueSession.close();
100             }
101             if (queueConnection != null) {
102                 queueConnection.close();
103             }
104         } catch (JMSException ex) {
105             LOGGER.error("Error closing " + getName(), ex);
106         }
107     }
108 
109     /**
110      * Data for the factory.
111      */
112     private static class FactoryData {
113         private String factoryName;
114         private String providerURL;
115         private String urlPkgPrefixes;
116         private String securityPrincipalName;
117         private String securityCredentials;
118         private String factoryBindingName;
119         private String queueBindingName;
120         private String userName;
121         private String password;
122 
123         public FactoryData(String factoryName, String providerURL, String urlPkgPrefixes, String securityPrincipalName,
124                            String securityCredentials, String factoryBindingName, String queueBindingName,
125                            String userName, String password) {
126             this.factoryName = factoryName;
127             this.providerURL = providerURL;
128             this.urlPkgPrefixes = urlPkgPrefixes;
129             this.securityPrincipalName = securityPrincipalName;
130             this.securityCredentials = securityCredentials;
131             this.factoryBindingName = factoryBindingName;
132             this.queueBindingName = queueBindingName;
133             this.userName = userName;
134             this.password = password;
135         }
136     }
137 
138     /**
139      * Factory to create the JMSQueueManager.
140      */
141     private static class JMSQueueManagerFactory implements ManagerFactory<JMSQueueManager, FactoryData> {
142 
143         public JMSQueueManager createManager(String name, FactoryData data) {
144             try {
145                 Context ctx = createContext(data.factoryName, data.providerURL, data.urlPkgPrefixes,
146                                             data.securityPrincipalName, data.securityCredentials);
147                 QueueConnectionFactory factory = (QueueConnectionFactory) lookup(ctx, data.factoryBindingName);
148                 QueueConnection conn;
149                 if (data.userName != null) {
150                     conn = factory.createQueueConnection(data.userName, data.password);
151                 } else {
152                     conn = factory.createQueueConnection();
153                 }
154                 QueueSession sess = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
155                 Queue queue = (Queue) lookup(ctx, data.queueBindingName);
156                 QueueSender sender = sess.createSender(queue);
157                 conn.start();
158                 return new JMSQueueManager(name, conn, sess, sender);
159 
160             } catch (NamingException ex) {
161                 LOGGER.error("Unable to locate resource", ex);
162             } catch (JMSException jmsex) {
163                 LOGGER.error("Unable to establish connection", jmsex);
164             }
165 
166             return null;
167         }
168     }
169 }