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.Queue; 023 import javax.jms.QueueConnection; 024 import javax.jms.QueueConnectionFactory; 025 import javax.jms.QueueSender; 026 import javax.jms.QueueSession; 027 import javax.jms.Session; 028 import javax.naming.Context; 029 import javax.naming.NamingException; 030 import java.io.Serializable; 031 032 /** 033 * Manager for a JMS Queue. 034 */ 035 public class JMSQueueManager extends AbstractJMSManager { 036 037 private static final JMSQueueManagerFactory factory = new JMSQueueManagerFactory(); 038 039 private final QueueConnection queueConnection; 040 private final QueueSession queueSession; 041 private final QueueSender queueSender; 042 043 /** 044 * The Constructor. 045 * @param name The unique name of the connection. 046 * @param conn The QueueConnection. 047 * @param sess The QueueSession. 048 * @param sender The QueueSender. 049 */ 050 protected JMSQueueManager(String name, QueueConnection conn, QueueSession sess, QueueSender sender) { 051 super(name); 052 this.queueConnection = conn; 053 this.queueSession = sess; 054 this.queueSender = sender; 055 } 056 057 /** 058 * Obtain a JMSQueueManager. 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 QueueConnectionFactory. 066 * @param queueBindingName The name to use to locate the Queue. 067 * @param userName The userid to use to create the Queue Connection. 068 * @param password The password to use to create the Queue Connection. 069 * @return The JMSQueueManager. 070 */ 071 public static JMSQueueManager getJMSQueueManager(String factoryName, String providerURL, String urlPkgPrefixes, 072 String securityPrincipalName, String securityCredentials, 073 String factoryBindingName, String queueBindingName, 074 String userName, String password) { 075 076 if (factoryBindingName == null) { 077 LOGGER.error("No factory name provided for JMSQueueManager"); 078 return null; 079 } 080 if (queueBindingName == null) { 081 LOGGER.error("No topic name provided for JMSQueueManager"); 082 return null; 083 } 084 085 String name = "JMSQueue:" + factoryBindingName + '.' + queueBindingName; 086 return getManager(name, factory, new FactoryData(factoryName, providerURL, urlPkgPrefixes, 087 securityPrincipalName, securityCredentials, factoryBindingName, queueBindingName, userName, password)); 088 } 089 090 @Override 091 public void send(Serializable object) throws Exception { 092 super.send(object, queueSession, queueSender); 093 } 094 095 @Override 096 public void releaseSub() { 097 try { 098 if (queueSession != null) { 099 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 }