/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2004-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.messaging.jmq.jmsserver.audit;
import com.sun.messaging.jmq.util.log.Logger;
import com.sun.messaging.jmq.jmsserver.Globals;
import com.sun.messaging.jmq.jmsserver.license.LicenseBase;
import com.sun.messaging.jmq.jmsserver.resources.*;
import com.sun.messaging.jmq.jmsserver.util.BrokerException;
import com.sun.messaging.jmq.jmsservice.BrokerEvent;
/**
* This class contains a static method to obtain a singleton MQAuditSession
* instance which takes care of writing audit logs for the rest of
* the broker.
* It is also a service factory for obtaining instances of a MQAuditSession
* for various types of implementations.
* <p>
* Audit logging is an EE feature.
*
* @version 1.6
*/
public class MQAuditService {
static Logger logger = null;
static BrokerResources br = null;
// whether auditing is allowed (auditing is an EE feature)
public static boolean AUDIT_LOGGING_LICENSED = false;
// -------------------------------------------------------------------
//
// Private define constants
//
// -------------------------------------------------------------------
// Property names for configuration properties and values
// public properties:
// imq.audit.enabled
//
// private properties:
// imq.audit.bsm.disabled
// imq.audit.<type>.class
public static final String AUDIT_PROP_PREFIX = Globals.IMQ + ".audit.";
public static final String AUDIT_ENABLED_PROP
= AUDIT_PROP_PREFIX + "enabled";
private static final String CLASS_PROP_SUBFIX = ".class";
// types of MQAuditSession implementation
public static final String BSM_TYPE = "bsm";
public static final String LOG_TYPE = "log";
// default values
private static final String DEFAULT_LOG_CLASS =
"com.sun.messaging.jmq.jmsserver.audit.LogAuditSession";
private static final String DEFAULT_BSM_CLASS =
"com.sun.messaging.jmq.jmsserver.audit.BSMAuditSession";
private static final String MQ_AUDIT_CLASS =
"com.sun.messaging.jmq.jmsserver.audit.MQAuditManager";
// Solaris Java based BSM audit interface
private static final String BSM_CLASS = "com.sun.audit.AuditSession";
// default value for whether BSM is disabled or not
static boolean DEFAULT_BSM_DISABLED = true;
static boolean bsmDisabled = DEFAULT_BSM_DISABLED;
// indicate whether BSM audit logging is to be initiated
// true iff
// - auditing is licensed
// - BSM is not disabled (by private property imq.audit.bsm.disabled)
// - BSM library is available
static boolean bsmAudit = false;
// indicate whether audit records should be written in broker's log file
static boolean logAuditEnabled = false;
public static void clear() {
logger = null;
br = null;
auditSession = null;
}
public static void init() {
logger = Globals.getLogger();
br = Globals.getBrokerResources();
try {
// Audit logging is an EE feature
LicenseBase license = Globals.getCurrentLicense(null);
AUDIT_LOGGING_LICENSED = license.getBooleanProperty(
license.PROP_ENABLE_AUDIT_CCC, false);
} catch (BrokerException ex) {
AUDIT_LOGGING_LICENSED = false;
}
// check private property
bsmDisabled = Globals.getConfig().getBooleanProperty(
"imq.audit.bsm.disabled", DEFAULT_BSM_DISABLED);
if (AUDIT_LOGGING_LICENSED && !bsmDisabled) {
// check whether BSM auditing is avaliable
try {
Class.forName(BSM_CLASS);
bsmAudit = true;
} catch (Throwable t) {
logger.log(logger.DEBUGHIGH, BSM_CLASS
+ " not found:BSM audit not available:" + t);
}
}
}
// Singleton MQAuditSession
static private MQAuditSession auditSession = null;
// -------------------------------------------------------------------
//
// Public static methods
//
// -------------------------------------------------------------------
/**
* The getAuditSession method returns a singleton instance of the
* MQAuditManager class which is responsible for writing audit records
* according to what is configured and what platform specific auditing
* implementation is available.
*
* @return a reference to a MQAuditSession instance.
*/
public static synchronized MQAuditSession getAuditSession()
throws BrokerException {
if (auditSession == null) {
// license check
// if auditing is not licensed and the imq.audit.enabled
// property is set to true; log error and exit
logAuditEnabled = Globals.getConfig().getBooleanProperty(
AUDIT_ENABLED_PROP, false);
if (!AUDIT_LOGGING_LICENSED && logAuditEnabled) {
// check if we need to throw exception
Globals.getLogger().log(Logger.ERROR,
BrokerResources.E_FATAL_FEATURE_UNAVAILABLE,
Globals.getBrokerResources().getString(
BrokerResources.M_AUDIT_FEATURE));
com.sun.messaging.jmq.jmsserver.Broker.getBroker().exit(
com.sun.messaging.jmq.util.BrokerExitCode.ERROR,
Globals.getBrokerResources().getString(
BrokerResources.M_AUDIT_FEATURE),
BrokerEvent.Type.FATAL_ERROR);
}
// Create a new audit session. May throw an audit exception.
auditSession = createAuditSession();
}
// Return the audit session instance.
return auditSession;
}
// Create a new audit session according to the specified type.
static MQAuditSession getAuditSession(String type)
throws BrokerException {
String classname = null;
if (LOG_TYPE.equals(type)) {
classname = DEFAULT_LOG_CLASS;
} else if (BSM_TYPE.equals(type)) {
classname = DEFAULT_BSM_CLASS;
} else {
throw new BrokerException(
"UNEXPECTED AUDIT TYPE SPECIFIED: " + type);
}
String prop = AUDIT_PROP_PREFIX + type + CLASS_PROP_SUBFIX;
classname = Globals.getConfig().getProperty(prop, classname);
MQAuditSession asession = null;
Exception exception = null;
try {
asession = (MQAuditSession)Class.forName(classname).newInstance();
} catch (ClassNotFoundException e) {
exception = e;
} catch (InstantiationException e) {
exception = e;
} catch (IllegalAccessException e) {
exception = e;
} finally {
if (exception != null) {
if (exception instanceof BrokerException) {
throw (BrokerException)exception;
} else {
throw new BrokerException(
br.getString(br.X_FAILED_TO_GET_AUDIT_SESSION,
classname), exception);
}
}
}
return asession;
}
// -------------------------------------------------------------------
//
// Private static methods
//
// -------------------------------------------------------------------
/**
* Returns a singleton instance of the MQAuditManager class which
* is responsible for writing audit records according to what is
* configured and what platform specific auditing implementation
* is available.
*/
private static MQAuditSession createAuditSession()
throws BrokerException {
MQAuditSession asession = null;
Exception exception = null;
try {
asession = (MQAuditSession)Class.forName(MQ_AUDIT_CLASS).newInstance();
} catch (ClassNotFoundException e) {
exception = e;
} catch (InstantiationException e) {
exception = e;
} catch (IllegalAccessException e) {
exception = e;
} finally {
if (exception != null) {
if (exception instanceof BrokerException) {
throw (BrokerException)exception;
} else {
throw new BrokerException(
br.getString(br.X_FAILED_TO_GET_AUDIT_SESSION,
MQ_AUDIT_CLASS), exception);
}
}
}
return asession;
}
}