Created
October 28, 2016 14:11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.xdi.oxauth.audit; | |
/* | |
* Licensed to the Apache Software Foundation (ASF) under one or more | |
* contributor license agreements. See the NOTICE file distributed with | |
* this work for additional information regarding copyright ownership. | |
* The ASF licenses this file to You under the Apache License, Version 2.0 | |
* (the "License"); you may not use this file except in compliance with | |
* the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import org.apache.log4j.AppenderSkeleton; | |
import org.apache.log4j.helpers.LogLog; | |
import org.apache.log4j.spi.ErrorCode; | |
import org.apache.log4j.spi.LoggingEvent; | |
import javax.jms.*; | |
import javax.naming.Context; | |
import javax.naming.InitialContext; | |
import javax.naming.NameNotFoundException; | |
import javax.naming.NamingException; | |
import java.util.Properties; | |
public class JMSQueueAppender extends AppenderSkeleton { | |
String securityPrincipalName; | |
String securityCredentials; | |
String initialContextFactoryName; | |
String urlPkgPrefixes; | |
String providerURL; | |
String queueBindingName; | |
String qcfBindingName; | |
String userName; | |
String password; | |
boolean locationInfo; | |
QueueConnection queueConnection; | |
QueueSession queueSession; | |
QueueSender queueSender; | |
public JMSQueueAppender() { | |
} | |
/** | |
* Returns the value of the <b>QueueConnectionFactoryBindingName</b> option. | |
*/ | |
public String getQueueConnectionFactoryBindingName() { | |
return qcfBindingName; | |
} | |
/** | |
* The <b>QueueConnectionFactoryBindingName</b> option takes a | |
* string value. Its value will be used to lookup the appropriate | |
* <code>QueueConnectionFactory</code> from the JNDI context. | |
*/ | |
public void setQueueConnectionFactoryBindingName(String qcfBindingName) { | |
this.qcfBindingName = qcfBindingName; | |
} | |
/** | |
* Returns the value of the <b>QueueBindingName</b> option. | |
*/ | |
public String getQueueBindingName() { | |
return queueBindingName; | |
} | |
/** | |
* The <b>QueueBindingName</b> option takes a | |
* string value. Its value will be used to lookup the appropriate | |
* <code>Queue</code> from the JNDI context. | |
*/ | |
public void setQueueBindingName(String queueBindingName) { | |
this.queueBindingName = queueBindingName; | |
} | |
/** | |
* Returns value of the <b>LocationInfo</b> property which | |
* determines whether location (stack) info is sent to the remote | |
* subscriber. | |
*/ | |
public boolean getLocationInfo() { | |
return locationInfo; | |
} | |
/** | |
* If true, the information sent to the remote subscriber will | |
* include caller's location information. By default no location | |
* information is sent to the subscriber. | |
*/ | |
public void setLocationInfo(boolean locationInfo) { | |
this.locationInfo = locationInfo; | |
} | |
/** | |
* Options are activated and become effective only after calling | |
* this method. | |
*/ | |
public void activateOptions() { | |
QueueConnectionFactory queueConnectionFactory; | |
try { | |
Context jndi; | |
LogLog.debug("Getting initial context."); | |
if (initialContextFactoryName != null) { | |
Properties env = new Properties(); | |
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName); | |
if (providerURL != null) { | |
env.put(Context.PROVIDER_URL, providerURL); | |
} else { | |
LogLog.warn("You have set InitialContextFactoryName option but not the " | |
+ "ProviderURL. This is likely to cause problems."); | |
} | |
if (urlPkgPrefixes != null) { | |
env.put(Context.URL_PKG_PREFIXES, urlPkgPrefixes); | |
} | |
if (securityPrincipalName != null) { | |
env.put(Context.SECURITY_PRINCIPAL, securityPrincipalName); | |
if (securityCredentials != null) { | |
env.put(Context.SECURITY_CREDENTIALS, securityCredentials); | |
} else { | |
LogLog.warn("You have set SecurityPrincipalName option but not the " | |
+ "SecurityCredentials. This is likely to cause problems."); | |
} | |
} | |
jndi = new InitialContext(env); | |
} else { | |
jndi = new InitialContext(); | |
} | |
LogLog.debug("Looking up [" + qcfBindingName + "]"); | |
queueConnectionFactory = (QueueConnectionFactory) lookup(jndi, qcfBindingName); | |
LogLog.debug("About to create QueueConnection."); | |
if (userName != null) { | |
queueConnection = queueConnectionFactory.createQueueConnection(userName, | |
password); | |
} else { | |
queueConnection = queueConnectionFactory.createQueueConnection(); | |
} | |
LogLog.debug("Creating QueueSession, non-transactional, " | |
+ "in AUTO_ACKNOWLEDGE mode."); | |
queueSession = queueConnection.createQueueSession(false, | |
Session.AUTO_ACKNOWLEDGE); | |
LogLog.debug("Looking up queue name [" + queueBindingName + "]."); | |
Queue queue = (Queue) lookup(jndi, queueBindingName); | |
LogLog.debug("Creating QueuePublisher."); | |
queueSender = queueSession.createSender(queue); | |
LogLog.debug("Starting QueueConnection."); | |
queueConnection.start(); | |
jndi.close(); | |
} catch (JMSException e) { | |
errorHandler.error("Error while activating options for appender named [" + name + | |
"].", e, ErrorCode.GENERIC_FAILURE); | |
} catch (NamingException e) { | |
errorHandler.error("Error while activating options for appender named [" + name + | |
"].", e, ErrorCode.GENERIC_FAILURE); | |
} catch (RuntimeException e) { | |
errorHandler.error("Error while activating options for appender named [" + name + | |
"].", e, ErrorCode.GENERIC_FAILURE); | |
} | |
} | |
protected Object lookup(Context ctx, String name) throws NamingException { | |
try { | |
return ctx.lookup(name); | |
} catch (NameNotFoundException e) { | |
LogLog.error("Could not find name [" + name + "]."); | |
throw e; | |
} | |
} | |
protected boolean checkEntryConditions() { | |
String fail = null; | |
if (this.queueConnection == null) { | |
fail = "No QueueConnection"; | |
} else if (this.queueSession == null) { | |
fail = "No QueueSession"; | |
} else if (this.queueSender == null) { | |
fail = "No QueuePublisher"; | |
} | |
if (fail != null) { | |
errorHandler.error(fail + " for JMSAppender named [" + name + "]."); | |
return false; | |
} else { | |
return true; | |
} | |
} | |
/** | |
* Close this JMSAppender. Closing releases all resources used by the | |
* appender. A closed appender cannot be re-opened. | |
*/ | |
public synchronized void close() { | |
// The synchronized modifier avoids concurrent append and close operations | |
if (this.closed) { | |
return; | |
} | |
LogLog.debug("Closing appender [" + name + "]."); | |
this.closed = true; | |
try { | |
if (queueSession != null) { | |
queueSession.close(); | |
} | |
if (queueConnection != null) { | |
queueConnection.close(); | |
} | |
} catch (JMSException e) { | |
LogLog.error("Error while closing JMSAppender [" + name + "].", e); | |
} catch (RuntimeException e) { | |
LogLog.error("Error while closing JMSAppender [" + name + "].", e); | |
} | |
// Help garbage collection | |
queueSender = null; | |
queueSession = null; | |
queueConnection = null; | |
} | |
/** | |
* This method called by {@link AppenderSkeleton#doAppend} method to | |
* do most of the real appending work. | |
*/ | |
public void append(LoggingEvent event) { | |
if (!checkEntryConditions()) { | |
return; | |
} | |
try { | |
ObjectMessage msg = queueSession.createObjectMessage(); | |
if (locationInfo) { | |
event.getLocationInformation(); | |
} | |
msg.setObject(event); | |
queueSender.send(msg); | |
} catch (JMSException e) { | |
errorHandler.error("Could not publish message in JMSAppender [" + name + "].", e, | |
ErrorCode.GENERIC_FAILURE); | |
} catch (RuntimeException e) { | |
errorHandler.error("Could not publish message in JMSAppender [" + name + "].", e, | |
ErrorCode.GENERIC_FAILURE); | |
} | |
} | |
/** | |
* Returns the value of the <b>InitialContextFactoryName</b> option. | |
* See {@link #setInitialContextFactoryName} for more details on the | |
* meaning of this option. | |
*/ | |
public String getInitialContextFactoryName() { | |
return initialContextFactoryName; | |
} | |
/** | |
* Setting the <b>InitialContextFactoryName</b> method will cause | |
* this <code>JMSAppender</code> instance to use the {@link | |
* InitialContext#InitialContext(Hashtable)} method instead of the | |
* no-argument constructor. If you set this option, you should also | |
* at least set the <b>ProviderURL</b> option. | |
* | |
* @see #setProviderURL(String) | |
*/ | |
public void setInitialContextFactoryName(String initialContextFactoryName) { | |
this.initialContextFactoryName = initialContextFactoryName; | |
} | |
public String getProviderURL() { | |
return providerURL; | |
} | |
public void setProviderURL(String providerURL) { | |
this.providerURL = providerURL; | |
} | |
String getURLPkgPrefixes() { | |
return urlPkgPrefixes; | |
} | |
public void setURLPkgPrefixes(String urlPkgPrefixes) { | |
this.urlPkgPrefixes = urlPkgPrefixes; | |
} | |
public String getSecurityCredentials() { | |
return securityCredentials; | |
} | |
public void setSecurityCredentials(String securityCredentials) { | |
this.securityCredentials = securityCredentials; | |
} | |
public String getSecurityPrincipalName() { | |
return securityPrincipalName; | |
} | |
public void setSecurityPrincipalName(String securityPrincipalName) { | |
this.securityPrincipalName = securityPrincipalName; | |
} | |
public String getUserName() { | |
return userName; | |
} | |
/** | |
* The user name to use when {@link | |
* QueueConnectionFactory#createQueueConnection(String, String) | |
* creating a queue session}. If you set this option, you should | |
* also set the <b>Password</b> option. See {@link | |
* #setPassword(String)}. | |
*/ | |
public void setUserName(String userName) { | |
this.userName = userName; | |
} | |
public String getPassword() { | |
return password; | |
} | |
/** | |
* The paswword to use when creating a queue session. | |
*/ | |
public void setPassword(String password) { | |
this.password = password; | |
} | |
/** | |
* Returns the QueueConnection used for this appender. Only valid after | |
* activateOptions() method has been invoked. | |
*/ | |
protected QueueConnection getQueueConnection() { | |
return queueConnection; | |
} | |
/** | |
* Returns the QueueSession used for this appender. Only valid after | |
* activateOptions() method has been invoked. | |
*/ | |
protected QueueSession getQueueSession() { | |
return queueSession; | |
} | |
/** | |
* Returns the QueueSender used for this appender. Only valid after | |
* activateOptions() method has been invoked. | |
*/ | |
protected QueueSender getQueueSender() { | |
return queueSender; | |
} | |
/** | |
* The JMSAppender sends serialized events and consequently does not | |
* require a layout. | |
*/ | |
public boolean requiresLayout() { | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment