001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017 package org.apache.logging.log4j.core.net; 018 019 import org.apache.logging.log4j.core.appender.ManagerFactory; 020 021 import javax.jms.JMSException; 022 import javax.jms.Session; 023 import javax.jms.Topic; 024 import javax.jms.TopicConnection; 025 import javax.jms.TopicConnectionFactory; 026 import javax.jms.TopicPublisher; 027 import javax.jms.TopicSession; 028 import javax.naming.Context; 029 import javax.naming.NamingException; 030 import java.io.Serializable; 031 032 /** 033 * Manager for JMS Topic connections. 034 */ 035 public class JMSTopicManager extends AbstractJMSManager { 036 037 private static final JMSTopicManagerFactory factory = new JMSTopicManagerFactory(); 038 039 private final TopicConnection topicConnection; 040 private final TopicSession topicSession; 041 private final TopicPublisher topicPublisher; 042 043 /** 044 * Constructor. 045 * @param name The unique name of the connection. 046 * @param conn The TopicConnection. 047 * @param sess The TopicSession. 048 * @param pub The TopicPublisher. 049 */ 050 public JMSTopicManager(String name, TopicConnection conn, TopicSession sess, TopicPublisher pub) { 051 super(name); 052 this.topicConnection = conn; 053 this.topicSession = sess; 054 this.topicPublisher = pub; 055 } 056 057 /** 058 * Obtain a JSMTopicManager. 059 * @param factoryName The fully qualified class name of the InitialContextFactory. 060 * @param providerURL The URL of the provider to use. 061 * @param urlPkgPrefixes A colon-separated list of package prefixes for the class name of the factory class that 062 * will create a URL context factory 063 * @param securityPrincipalName The name of the identity of the Principal. 064 * @param securityCredentials The security credentials of the Principal. 065 * @param factoryBindingName The name to locate in the Context that provides the TopicConnectionFactory. 066 * @param topicBindingName The name to use to locate the Topic. 067 * @param userName The userid to use to create the Topic Connection. 068 * @param password The password to use to create the Topic Connection. 069 * @return A JMSTopicManager. 070 */ 071 public static JMSTopicManager getJMSTopicManager(String factoryName, String providerURL, String urlPkgPrefixes, 072 String securityPrincipalName, String securityCredentials, 073 String factoryBindingName, String topicBindingName, 074 String userName, String password) { 075 076 if (factoryBindingName == null) { 077 LOGGER.error("No factory name provided for JMSTopicManager"); 078 return null; 079 } 080 if (topicBindingName == null) { 081 LOGGER.error("No topic name provided for JMSTopicManager"); 082 return null; 083 } 084 085 String name = "JMSTopic:" + factoryBindingName + '.' + topicBindingName; 086 return getManager(name, factory, new FactoryData(factoryName, providerURL, urlPkgPrefixes, 087 securityPrincipalName, securityCredentials, factoryBindingName, topicBindingName, userName, password)); 088 } 089 090 091 @Override 092 public void send(Serializable object) throws Exception { 093 super.send(object, topicSession, topicPublisher); 094 } 095 096 @Override 097 public void releaseSub() { 098 try { 099 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 }