Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save worm333/fd60ed5535878c423c228ccb7617748e to your computer and use it in GitHub Desktop.
Save worm333/fd60ed5535878c423c228ccb7617748e to your computer and use it in GitHub Desktop.
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