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.Session;
23  import javax.jms.Topic;
24  import javax.jms.TopicConnection;
25  import javax.jms.TopicConnectionFactory;
26  import javax.jms.TopicPublisher;
27  import javax.jms.TopicSession;
28  import javax.naming.Context;
29  import javax.naming.NamingException;
30  import java.io.Serializable;
31  
32  /**
33   * Manager for JMS Topic connections.
34   */
35  public class JMSTopicManager extends AbstractJMSManager {
36  
37      private static final JMSTopicManagerFactory factory = new JMSTopicManagerFactory();
38  
39      private final TopicConnection topicConnection;
40      private final TopicSession topicSession;
41      private final TopicPublisher topicPublisher;
42  
43      /**
44       * Constructor.
45       * @param name The unique name of the connection.
46       * @param conn The TopicConnection.
47       * @param sess The TopicSession.
48       * @param pub The TopicPublisher.
49       */
50      public JMSTopicManager(String name, TopicConnection conn, TopicSession sess, TopicPublisher pub) {
51          super(name);
52          this.topicConnection = conn;
53          this.topicSession = sess;
54          this.topicPublisher = pub;
55      }
56  
57      /**
58       * Obtain a JSMTopicManager.
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 TopicConnectionFactory.
66       * @param topicBindingName The name to use to locate the Topic.
67       * @param userName The userid to use to create the Topic Connection.
68       * @param password The password to use to create the Topic Connection.
69       * @return A JMSTopicManager.
70       */
71      public static JMSTopicManager getJMSTopicManager(String factoryName, String providerURL, String urlPkgPrefixes,
72                                                       String securityPrincipalName, String securityCredentials,
73                                                       String factoryBindingName, String topicBindingName,
74                                                       String userName, String password) {
75  
76          if (factoryBindingName == null) {
77              LOGGER.error("No factory name provided for JMSTopicManager");
78              return null;
79          }
80          if (topicBindingName == null) {
81              LOGGER.error("No topic name provided for JMSTopicManager");
82              return null;
83          }
84  
85          String name = "JMSTopic:" + factoryBindingName + '.' + topicBindingName;
86          return getManager(name, factory, new FactoryData(factoryName, providerURL, urlPkgPrefixes,
87              securityPrincipalName, securityCredentials, factoryBindingName, topicBindingName, userName, password));
88      }
89  
90  
91      @Override
92      public void send(Serializable object) throws Exception {
93          super.send(object, topicSession, topicPublisher);
94      }
95  
96      @Override
97      public void releaseSub() {
98          try {
99              if (topicSession != null) {
100                 topicSession.close();
101             }
102             if (topicConnection != null) {
103                 topicConnection.close();
104             }
105         } catch (JMSException ex) {
106             LOGGER.error("Error closing " + getName(), ex);
107         }
108     }
109 
110     /**
111      * Data for the factory.
112      */
113     private static class FactoryData {
114         private String factoryName;
115         private String providerURL;
116         private String urlPkgPrefixes;
117         private String securityPrincipalName;
118         private String securityCredentials;
119         private String factoryBindingName;
120         private String topicBindingName;
121         private String userName;
122         private String password;
123 
124         public FactoryData(String factoryName, String providerURL, String urlPkgPrefixes, String securityPrincipalName,
125                            String securityCredentials, String factoryBindingName, String topicBindingName,
126                            String userName, String password) {
127             this.factoryName = factoryName;
128             this.providerURL = providerURL;
129             this.urlPkgPrefixes = urlPkgPrefixes;
130             this.securityPrincipalName = securityPrincipalName;
131             this.securityCredentials = securityCredentials;
132             this.factoryBindingName = factoryBindingName;
133             this.topicBindingName = topicBindingName;
134             this.userName = userName;
135             this.password = password;
136         }
137     }
138 
139     /**
140      * Factory to create a JMSTopicManager.
141      */
142     private static class JMSTopicManagerFactory implements ManagerFactory<JMSTopicManager, FactoryData> {
143 
144         public JMSTopicManager createManager(String name, FactoryData data) {
145             try {
146                 Context ctx = createContext(data.factoryName, data.providerURL, data.urlPkgPrefixes,
147                                             data.securityPrincipalName, data.securityCredentials);
148                 TopicConnectionFactory factory = (TopicConnectionFactory) lookup(ctx, data.factoryBindingName);
149                 TopicConnection conn;
150                 if (data.userName != null) {
151                     conn = factory.createTopicConnection(data.userName, data.password);
152                 } else {
153                     conn = factory.createTopicConnection();
154                 }
155                 TopicSession sess = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
156                 Topic topic = (Topic) lookup(ctx, data.topicBindingName);
157                 TopicPublisher pub = sess.createPublisher(topic);
158                 conn.start();
159                 return new JMSTopicManager(name, conn, sess, pub);
160             } catch (NamingException ex) {
161                 LOGGER.error("Bad Name " + data.topicBindingName, ex);
162             } catch (JMSException jmsex) {
163                 LOGGER.error("Unable to create publisher ", jmsex);
164             }
165 
166             return null;
167         }
168     }
169 }