ARTEMIS-2648 - audit logging improvements
https://issues.apache.org/jira/browse/ARTEMIS-2648
This commit is contained in:
parent
00985b609f
commit
8a04ee07de
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
# Additional logger names to configure (root logger is always configured)
|
# Additional logger names to configure (root logger is always configured)
|
||||||
# Root logger option
|
# Root logger option
|
||||||
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message
|
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message,org.apache.activemq.audit.resource
|
||||||
|
|
||||||
# Root logger level
|
# Root logger level
|
||||||
logger.level=INFO
|
logger.level=INFO
|
||||||
|
@ -36,6 +36,10 @@ logger.org.apache.activemq.audit.base.level=ERROR
|
||||||
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
||||||
|
|
||||||
|
logger.org.apache.activemq.audit.resource.level=ERROR
|
||||||
|
logger.org.apache.activemq.audit.resource.handlers=AUDIT_FILE
|
||||||
|
logger.org.apache.activemq.audit.resource.useParentHandlers=false
|
||||||
|
|
||||||
logger.org.apache.activemq.audit.message.level=ERROR
|
logger.org.apache.activemq.audit.message.level=ERROR
|
||||||
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
||||||
|
|
|
@ -23,10 +23,12 @@ import org.jboss.logging.annotations.LogMessage;
|
||||||
import org.jboss.logging.annotations.Message;
|
import org.jboss.logging.annotations.Message;
|
||||||
import org.jboss.logging.annotations.MessageLogger;
|
import org.jboss.logging.annotations.MessageLogger;
|
||||||
|
|
||||||
|
import javax.management.ObjectName;
|
||||||
import javax.security.auth.Subject;
|
import javax.security.auth.Subject;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger Code 60
|
* Logger Code 60
|
||||||
|
@ -46,26 +48,81 @@ import java.util.Arrays;
|
||||||
public interface AuditLogger extends BasicLogger {
|
public interface AuditLogger extends BasicLogger {
|
||||||
|
|
||||||
AuditLogger LOGGER = Logger.getMessageLogger(AuditLogger.class, "org.apache.activemq.audit.base");
|
AuditLogger LOGGER = Logger.getMessageLogger(AuditLogger.class, "org.apache.activemq.audit.base");
|
||||||
|
AuditLogger RESOURCE_LOGGER = Logger.getMessageLogger(AuditLogger.class, "org.apache.activemq.audit.resource");
|
||||||
AuditLogger MESSAGE_LOGGER = Logger.getMessageLogger(AuditLogger.class, "org.apache.activemq.audit.message");
|
AuditLogger MESSAGE_LOGGER = Logger.getMessageLogger(AuditLogger.class, "org.apache.activemq.audit.message");
|
||||||
|
|
||||||
|
ThreadLocal<String> remoteUrl = new ThreadLocal<>();
|
||||||
|
|
||||||
|
ThreadLocal<Subject> currentCaller = new ThreadLocal<>();
|
||||||
|
|
||||||
|
static boolean isAnyLoggingEnabled() {
|
||||||
|
return isEnabled() || isMessageEnabled() || isResourceLoggingEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
static boolean isEnabled() {
|
static boolean isEnabled() {
|
||||||
return LOGGER.isEnabled(Logger.Level.INFO);
|
return LOGGER.isEnabled(Logger.Level.INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isResourceLoggingEnabled() {
|
||||||
|
return RESOURCE_LOGGER.isEnabled(Logger.Level.INFO);
|
||||||
|
}
|
||||||
|
|
||||||
static boolean isMessageEnabled() {
|
static boolean isMessageEnabled() {
|
||||||
return MESSAGE_LOGGER.isEnabled(Logger.Level.INFO);
|
return MESSAGE_LOGGER.isEnabled(Logger.Level.INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getCaller() {
|
static String getCaller() {
|
||||||
Subject subject = Subject.getSubject(AccessController.getContext());
|
Subject subject = Subject.getSubject(AccessController.getContext());
|
||||||
String caller = "anonymous";
|
if (subject == null) {
|
||||||
|
subject = currentCaller.get();
|
||||||
|
}
|
||||||
|
return getCaller(subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getCaller(String user) {
|
||||||
|
Subject subject = Subject.getSubject(AccessController.getContext());
|
||||||
|
if (subject == null) {
|
||||||
|
subject = currentCaller.get();
|
||||||
|
}
|
||||||
|
if (subject == null) {
|
||||||
|
return user + (remoteUrl.get() == null ? "@unknown" : remoteUrl.get());
|
||||||
|
}
|
||||||
|
return getCaller(subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getCaller(Subject subject) {
|
||||||
|
String user = "anonymous";
|
||||||
|
String roles = "";
|
||||||
|
String url = remoteUrl.get() == null ? "@unknown" : remoteUrl.get();
|
||||||
if (subject != null) {
|
if (subject != null) {
|
||||||
caller = "";
|
Set<Principal> principals = subject.getPrincipals();
|
||||||
for (Principal principal : subject.getPrincipals()) {
|
for (Principal principal : principals) {
|
||||||
caller += principal.getName() + "|";
|
if (principal.getClass().getName().endsWith("UserPrincipal")) {
|
||||||
|
user = principal.getName();
|
||||||
|
} else if (principal.getClass().getName().endsWith("RolePrincipal")) {
|
||||||
|
roles = "(" + principal.getName() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return caller;
|
}
|
||||||
|
return user + roles + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setCurrentCaller(Subject caller) {
|
||||||
|
currentCaller.set(caller);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setRemoteAddress(String remoteAddress) {
|
||||||
|
String actualAddress;
|
||||||
|
if (remoteAddress.startsWith("/")) {
|
||||||
|
actualAddress = "@" + remoteAddress.substring(1);
|
||||||
|
} else {
|
||||||
|
actualAddress = "@" + remoteAddress;
|
||||||
|
}
|
||||||
|
remoteUrl.set(actualAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getRemoteAddress() {
|
||||||
|
return remoteUrl.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static String arrayToString(Object value) {
|
static String arrayToString(Object value) {
|
||||||
|
@ -201,7 +258,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
void getUnRoutedMessageCount(String user, Object source, Object... args);
|
void getUnRoutedMessageCount(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void sendMessage(Object source, String user, Object... args) {
|
static void sendMessage(Object source, String user, Object... args) {
|
||||||
LOGGER.sendMessage(user == null ? getCaller() : user, source, arrayToString(args));
|
LOGGER.sendMessage(getCaller(user), source, arrayToString(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@ -617,7 +674,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
void deployQueue(String user, Object source, Object... args);
|
void deployQueue(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void createQueue(Object source, String user, Object... args) {
|
static void createQueue(Object source, String user, Object... args) {
|
||||||
LOGGER.createQueue(user == null ? getCaller() : user, source, arrayToString(args));
|
RESOURCE_LOGGER.createQueue(getCaller(user), source, arrayToString(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@ -673,7 +730,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
void getAddressNames(String user, Object source, Object... args);
|
void getAddressNames(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void destroyQueue(Object source, String user, Object... args) {
|
static void destroyQueue(Object source, String user, Object... args) {
|
||||||
LOGGER.destroyQueue(user == null ? getCaller() : user, source, arrayToString(args));
|
LOGGER.destroyQueue(getCaller(user), source, arrayToString(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@ -2193,7 +2250,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
void getUniqueName(String user, Object source, Object... args);
|
void getUniqueName(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void serverSessionCreateAddress(Object source, String user, Object... args) {
|
static void serverSessionCreateAddress(Object source, String user, Object... args) {
|
||||||
LOGGER.serverSessionCreateAddress2(user == null ? getCaller() : user, source, arrayToString(args));
|
LOGGER.serverSessionCreateAddress2(getCaller(user), source, arrayToString(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@ -2201,7 +2258,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
void serverSessionCreateAddress2(String user, Object source, Object... args);
|
void serverSessionCreateAddress2(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void handleManagementMessage(Object source, String user, Object... args) {
|
static void handleManagementMessage(Object source, String user, Object... args) {
|
||||||
LOGGER.handleManagementMessage2(user == null ? getCaller() : user, source, arrayToString(args));
|
LOGGER.handleManagementMessage2(getCaller(user), source, arrayToString(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@ -2219,7 +2276,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
|
|
||||||
|
|
||||||
static void createCoreConsumer(Object source, String user, Object... args) {
|
static void createCoreConsumer(Object source, String user, Object... args) {
|
||||||
LOGGER.createCoreConsumer(user == null ? getCaller() : user, source, arrayToString(args));
|
LOGGER.createCoreConsumer(getCaller(user), source, arrayToString(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@ -2227,7 +2284,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
void createCoreConsumer(String user, Object source, Object... args);
|
void createCoreConsumer(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void createSharedQueue(Object source, String user, Object... args) {
|
static void createSharedQueue(Object source, String user, Object... args) {
|
||||||
LOGGER.createSharedQueue(user == null ? getCaller() : user, source, arrayToString(args));
|
LOGGER.createSharedQueue(getCaller(user), source, arrayToString(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@ -2250,22 +2307,12 @@ public interface AuditLogger extends BasicLogger {
|
||||||
@Message(id = 601268, value = "User {0} is getting produced message rate on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601268, value = "User {0} is getting produced message rate on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void getProducedRate(String user, Object source, Object... args);
|
void getProducedRate(String user, Object source, Object... args);
|
||||||
|
|
||||||
//hot path log using a different logger
|
|
||||||
static void coreSendMessage(Object source, String user, Object... args) {
|
|
||||||
MESSAGE_LOGGER.coreSendMessage(user == null ? getCaller() : user, source, arrayToString(args));
|
|
||||||
}
|
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
|
||||||
@Message(id = 601500, value = "User {0} is sending a core message on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
|
||||||
void coreSendMessage(String user, Object source, Object... args);
|
|
||||||
|
|
||||||
|
|
||||||
static void getAcknowledgeAttempts(Object source) {
|
static void getAcknowledgeAttempts(Object source) {
|
||||||
LOGGER.getMessagesAcknowledged(getCaller(), source);
|
LOGGER.getMessagesAcknowledged(getCaller(), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601501, value = "User {0} is getting messages acknowledged attempts on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601269, value = "User {0} is getting messages acknowledged attempts on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void getAcknowledgeAttempts(String user, Object source, Object... args);
|
void getAcknowledgeAttempts(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void getRingSize(Object source, Object... args) {
|
static void getRingSize(Object source, Object... args) {
|
||||||
|
@ -2273,7 +2320,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601502, value = "User {0} is getting ring size on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601270, value = "User {0} is getting ring size on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void getRingSize(String user, Object source, Object... args);
|
void getRingSize(String user, Object source, Object... args);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2282,7 +2329,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601503, value = "User {0} is getting retroactiveResource property on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601271, value = "User {0} is getting retroactiveResource property on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void isRetroactiveResource(String user, Object source, Object... args);
|
void isRetroactiveResource(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void getDiskStoreUsage(Object source) {
|
static void getDiskStoreUsage(Object source) {
|
||||||
|
@ -2290,7 +2337,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601504, value = "User {0} is getting disk store usage on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601272, value = "User {0} is getting disk store usage on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void getDiskStoreUsage(String user, Object source, Object... args);
|
void getDiskStoreUsage(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void getDiskStoreUsagePercentage(Object source) {
|
static void getDiskStoreUsagePercentage(Object source) {
|
||||||
|
@ -2298,7 +2345,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601505, value = "User {0} is getting disk store usage percentage on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601273, value = "User {0} is getting disk store usage percentage on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void getDiskStoreUsagePercentage(String user, Object source, Object... args);
|
void getDiskStoreUsagePercentage(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void isGroupRebalance(Object source) {
|
static void isGroupRebalance(Object source) {
|
||||||
|
@ -2306,7 +2353,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601506, value = "User {0} is getting group rebalance property on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601274, value = "User {0} is getting group rebalance property on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void isGroupRebalance(String user, Object source, Object... args);
|
void isGroupRebalance(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void getGroupBuckets(Object source) {
|
static void getGroupBuckets(Object source) {
|
||||||
|
@ -2314,7 +2361,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601507, value = "User {0} is getting group buckets on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601275, value = "User {0} is getting group buckets on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void getGroupBuckets(String user, Object source, Object... args);
|
void getGroupBuckets(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void getGroupFirstKey(Object source) {
|
static void getGroupFirstKey(Object source) {
|
||||||
|
@ -2322,7 +2369,7 @@ public interface AuditLogger extends BasicLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601508, value = "User {0} is getting group first key on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601276, value = "User {0} is getting group first key on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void getGroupFirstKey(String user, Object source, Object... args);
|
void getGroupFirstKey(String user, Object source, Object... args);
|
||||||
|
|
||||||
static void getCurrentDuplicateIdCacheSize(Object source) {
|
static void getCurrentDuplicateIdCacheSize(Object source) {
|
||||||
|
@ -2341,4 +2388,254 @@ public interface AuditLogger extends BasicLogger {
|
||||||
@LogMessage(level = Logger.Level.INFO)
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
@Message(id = 601510, value = "User {0} is clearing duplicate ID cache on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
@Message(id = 601510, value = "User {0} is clearing duplicate ID cache on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
void clearDuplicateIdCache(String user, Object source, Object... args);
|
void clearDuplicateIdCache(String user, Object source, Object... args);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This logger is for message production and consumption and is on the hot path so enabled independently
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
//hot path log using a different logger
|
||||||
|
static void coreSendMessage(String user, Object context) {
|
||||||
|
MESSAGE_LOGGER.sendMessage(getCaller(user), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601500, value = "User {0} is sending a core message with Context: {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void sendMessage(String user, Object context);
|
||||||
|
|
||||||
|
//hot path log using a different logger
|
||||||
|
static void coreConsumeMessage(String queue) {
|
||||||
|
MESSAGE_LOGGER.consumeMessage(getCaller(), queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601501, value = "User {0} is consuming a message from {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void consumeMessage(String user, String address);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This logger is focused on user interaction from the console or thru resource specific functions in the management layer/JMX
|
||||||
|
* */
|
||||||
|
|
||||||
|
static void createAddressSuccess(String name, String routingTypes) {
|
||||||
|
RESOURCE_LOGGER.createAddressSuccess(getCaller(), name, routingTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601701, value = "User {0} successfully created Address: {1} with routing types {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void createAddressSuccess(String user, String name, String routingTypes);
|
||||||
|
|
||||||
|
static void createAddressFailure(String name, String routingTypes) {
|
||||||
|
RESOURCE_LOGGER.createAddressFailure(getCaller(), name, routingTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601702, value = "User {0} failed to created Address: {1} with routing types {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void createAddressFailure(String user, String name, String routingTypes);
|
||||||
|
|
||||||
|
static void updateAddressSuccess(String name, String routingTypes) {
|
||||||
|
RESOURCE_LOGGER.updateAddressSuccess(getCaller(), name, routingTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601703, value = "User {0} successfully updated Address: {1} with routing types {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void updateAddressSuccess(String user, String name, String routingTypes);
|
||||||
|
|
||||||
|
static void updateAddressFailure(String name, String routingTypes) {
|
||||||
|
RESOURCE_LOGGER.updateAddressFailure(getCaller(), name, routingTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601704, value = "User {0} successfully updated Address: {1} with routing types {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void updateAddressFailure(String user, String name, String routingTypes);
|
||||||
|
|
||||||
|
static void deleteAddressSuccess(String name) {
|
||||||
|
RESOURCE_LOGGER.deleteAddressSuccess(getCaller(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601705, value = "User {0} successfully deleted Address: {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void deleteAddressSuccess(String user, String name);
|
||||||
|
|
||||||
|
|
||||||
|
static void deleteAddressFailure(String name) {
|
||||||
|
RESOURCE_LOGGER.deleteAddressFailure(getCaller(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601706, value = "User {0} failed to deleted Address: {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void deleteAddressFailure(String user, String name);
|
||||||
|
|
||||||
|
static void createQueueSuccess(String name, String address, String routingType) {
|
||||||
|
RESOURCE_LOGGER.createQueueSuccess(getCaller(), name, address, routingType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601707, value = "User {0} successfully created Queue: {1} on Address: {2} with routing type {3}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void createQueueSuccess(String user, String name, String address, String routingType);
|
||||||
|
|
||||||
|
static void createQueueFailure(String name, String address, String routingType) {
|
||||||
|
RESOURCE_LOGGER.createQueueFailure(getCaller(), name, address, routingType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601708, value = "User {0} failed to create Queue: {1} on Address: {2} with routing type {3}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void createQueueFailure(String user, String name, String address, String routingType);
|
||||||
|
|
||||||
|
static void updateQueueSuccess(String name, String routingType) {
|
||||||
|
RESOURCE_LOGGER.updateQueueSuccess(getCaller(), name, routingType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601709, value = "User {0} successfully updated Queue: {1} with routing type {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void updateQueueSuccess(String user, String name, String routingType);
|
||||||
|
|
||||||
|
static void updateQueueFailure(String name, String routingType) {
|
||||||
|
RESOURCE_LOGGER.updateQueueFailure(getCaller(), name, routingType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601710, value = "User {0} failed to update Queue: {1} with routing type {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void updateQueueFailure(String user, String name, String routingType);
|
||||||
|
|
||||||
|
|
||||||
|
static void destroyQueueSuccess(String name) {
|
||||||
|
RESOURCE_LOGGER.destroyQueueSuccess(getCaller(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601711, value = "User {0} successfully deleted Queue: {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void destroyQueueSuccess(String user, String name);
|
||||||
|
|
||||||
|
static void destroyQueueFailure(String name) {
|
||||||
|
RESOURCE_LOGGER.destroyQueueFailure(getCaller(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601712, value = "User {0} failed to delete Queue: {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void destroyQueueFailure(String user, String name);
|
||||||
|
|
||||||
|
static void removeMessagesSuccess(int removed, String queue) {
|
||||||
|
RESOURCE_LOGGER.removeMessagesSuccess(getCaller(), removed, queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601713, value = "User {0} has removed {1} messages from Queue: {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void removeMessagesSuccess(String user, int removed, String queue);
|
||||||
|
|
||||||
|
static void removeMessagesFailure(String queue) {
|
||||||
|
RESOURCE_LOGGER.removeMessagesFailure(getCaller(), queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601714, value = "User {0} failed to remove messages from Queue: {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void removeMessagesFailure(String user, String queue);
|
||||||
|
|
||||||
|
static void userSuccesfullyLoggedInAudit(Subject subject) {
|
||||||
|
RESOURCE_LOGGER.userSuccesfullyLoggedIn(getCaller(subject));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void userSuccesfullyLoggedInAudit() {
|
||||||
|
RESOURCE_LOGGER.userSuccesfullyLoggedIn(getCaller());
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601715, value = "User {0} successfully authorized", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void userSuccesfullyLoggedIn(String caller);
|
||||||
|
|
||||||
|
|
||||||
|
static void userFailedLoggedInAudit(String reason) {
|
||||||
|
RESOURCE_LOGGER.userFailedLoggedIn(getCaller(), reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void userFailedLoggedInAudit(Subject subject, String reason) {
|
||||||
|
RESOURCE_LOGGER.userFailedLoggedIn(getCaller(subject), reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601716, value = "User {0} failed authorization, reason: {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void userFailedLoggedIn(String user, String reason);
|
||||||
|
|
||||||
|
static void objectInvokedSuccessfully(ObjectName objectName, String operationName) {
|
||||||
|
RESOURCE_LOGGER.objectInvokedSuccessfully(getCaller(), objectName, operationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601717, value = "User {0} accessed {2} on management object {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void objectInvokedSuccessfully(String caller, ObjectName objectName, String operationName);
|
||||||
|
|
||||||
|
|
||||||
|
static void objectInvokedFailure(ObjectName objectName, String operationName) {
|
||||||
|
RESOURCE_LOGGER.objectInvokedFailure(getCaller(), objectName, operationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601718, value = "User {0} does not have correct role to access {2} on management object {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void objectInvokedFailure(String caller, ObjectName objectName, String operationName);
|
||||||
|
|
||||||
|
static void pauseQueueSuccess(String queueName) {
|
||||||
|
RESOURCE_LOGGER.pauseQueueSuccess(getCaller(), queueName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601719, value = "User {0} has paused queue {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void pauseQueueSuccess(String user, String queueName);
|
||||||
|
|
||||||
|
|
||||||
|
static void pauseQueueFailure(String queueName) {
|
||||||
|
RESOURCE_LOGGER.pauseQueueFailure(getCaller(), queueName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601720, value = "User {0} failed to pause queue {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void pauseQueueFailure(String user, String queueName);
|
||||||
|
|
||||||
|
|
||||||
|
static void resumeQueueSuccess(String queueName) {
|
||||||
|
RESOURCE_LOGGER.resumeQueueSuccess(getCaller(), queueName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601721, value = "User {0} has paused queue {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void resumeQueueSuccess(String user, String queueName);
|
||||||
|
|
||||||
|
|
||||||
|
static void resumeQueueFailure(String queueName) {
|
||||||
|
RESOURCE_LOGGER.pauseQueueFailure(getCaller(), queueName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601722, value = "User {0} failed to resume queue {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void resumeQueueFailure(String user, String queueName);
|
||||||
|
|
||||||
|
static void sendMessageSuccess(String queueName, String user) {
|
||||||
|
RESOURCE_LOGGER.sendMessageSuccess(getCaller(), queueName, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601723, value = "User {0} sent message to {1} as user {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void sendMessageSuccess(String user, String queueName, String sendUser);
|
||||||
|
|
||||||
|
static void sendMessageFailure(String queueName, String user) {
|
||||||
|
RESOURCE_LOGGER.sendMessageFailure(getCaller(), queueName, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601724, value = "User {0} failed to send message to {1} as user {2}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void sendMessageFailure(String user, String queueName, String sendUser);
|
||||||
|
|
||||||
|
static void browseMessagesSuccess(String queueName, int numMessages) {
|
||||||
|
RESOURCE_LOGGER.browseMessagesSuccess(getCaller(), queueName, numMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601725, value = "User {0} browsed {2} messages from queue {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void browseMessagesSuccess(String user, String queueName, int numMessages);
|
||||||
|
|
||||||
|
static void browseMessagesFailure(String queueName) {
|
||||||
|
RESOURCE_LOGGER.browseMessagesFailure(getCaller(), queueName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogMessage(level = Logger.Level.INFO)
|
||||||
|
@Message(id = 601726, value = "User {0} failed to browse messages from queue {1}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
void browseMessagesFailure(String user, String queueName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public abstract class AbstractRemotingConnection implements RemotingConnection {
|
||||||
protected final long creationTime;
|
protected final long creationTime;
|
||||||
protected volatile boolean dataReceived;
|
protected volatile boolean dataReceived;
|
||||||
private String clientId;
|
private String clientId;
|
||||||
|
private Subject subject;
|
||||||
|
|
||||||
public AbstractRemotingConnection(final Connection transportConnection, final Executor executor) {
|
public AbstractRemotingConnection(final Connection transportConnection, final Executor executor) {
|
||||||
this.transportConnection = transportConnection;
|
this.transportConnection = transportConnection;
|
||||||
|
@ -247,6 +248,16 @@ public abstract class AbstractRemotingConnection implements RemotingConnection {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuditSubject(Subject subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject getAuditSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getSubject() {
|
public Subject getSubject() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -219,6 +219,13 @@ public interface RemotingConnection extends BufferHandler {
|
||||||
*/
|
*/
|
||||||
boolean isSupportsFlowControl();
|
boolean isSupportsFlowControl();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sets the currently associated subject for this connection
|
||||||
|
* */
|
||||||
|
void setAuditSubject(Subject subject);
|
||||||
|
|
||||||
|
Subject getAuditSubject();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the possibly null identity associated with this connection
|
* the possibly null identity associated with this connection
|
||||||
* @return
|
* @return
|
||||||
|
|
|
@ -494,6 +494,16 @@ public class ChannelImplTest {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuditSubject(Subject subject) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject getAuditSubject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getSubject() {
|
public Subject getSubject() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class AMQPConnectionCallback implements FailureListener, CloseListener {
|
||||||
if (isPermittedMechanism(mechanism)) {
|
if (isPermittedMechanism(mechanism)) {
|
||||||
switch (mechanism) {
|
switch (mechanism) {
|
||||||
case PlainSASL.NAME:
|
case PlainSASL.NAME:
|
||||||
result = new PlainSASL(server.getSecurityStore(), manager.getSecurityDomain());
|
result = new PlainSASL(server.getSecurityStore(), manager.getSecurityDomain(), connection.getProtocolConnection());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnonymousServerSASL.NAME:
|
case AnonymousServerSASL.NAME:
|
||||||
|
|
|
@ -392,6 +392,11 @@ public class AMQPConnectionContext extends ProtonInitializable implements EventH
|
||||||
return connectionCallback.isWritable(readyListener);
|
return connectionCallback.isWritable(readyListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRemoteAddress() {
|
||||||
|
return connectionCallback.getTransportConnection().getRemoteAddress();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemoteOpen(Connection connection) throws Exception {
|
public void onRemoteOpen(Connection connection) throws Exception {
|
||||||
handler.requireHandler();
|
handler.requireHandler();
|
||||||
|
|
|
@ -91,4 +91,7 @@ public interface EventHandler {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default String getRemoteAddress() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.PooledByteBufAllocator;
|
import io.netty.buffer.PooledByteBufAllocator;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException;
|
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.apache.activemq.artemis.protocol.amqp.proton.AMQPConnectionContext;
|
import org.apache.activemq.artemis.protocol.amqp.proton.AMQPConnectionContext;
|
||||||
import org.apache.activemq.artemis.protocol.amqp.proton.ProtonInitializable;
|
import org.apache.activemq.artemis.protocol.amqp.proton.ProtonInitializable;
|
||||||
import org.apache.activemq.artemis.protocol.amqp.sasl.ClientSASL;
|
import org.apache.activemq.artemis.protocol.amqp.sasl.ClientSASL;
|
||||||
|
@ -492,6 +493,11 @@ public class ProtonHandler extends ProtonInitializable implements SaslListener {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
inDispatch = true;
|
inDispatch = true;
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
for (EventHandler h : handlers) {
|
||||||
|
AuditLogger.setRemoteAddress(h.getRemoteAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
while ((ev = collector.peek()) != null) {
|
while ((ev = collector.peek()) != null) {
|
||||||
for (EventHandler h : handlers) {
|
for (EventHandler h : handlers) {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
|
|
|
@ -17,22 +17,25 @@
|
||||||
package org.apache.activemq.artemis.protocol.amqp.sasl;
|
package org.apache.activemq.artemis.protocol.amqp.sasl;
|
||||||
|
|
||||||
import org.apache.activemq.artemis.core.security.SecurityStore;
|
import org.apache.activemq.artemis.core.security.SecurityStore;
|
||||||
|
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
|
||||||
|
|
||||||
public class PlainSASL extends ServerSASLPlain {
|
public class PlainSASL extends ServerSASLPlain {
|
||||||
|
|
||||||
private final SecurityStore securityStore;
|
private final SecurityStore securityStore;
|
||||||
private final String securityDomain;
|
private final String securityDomain;
|
||||||
|
private RemotingConnection remotingConnection;
|
||||||
|
|
||||||
public PlainSASL(SecurityStore securityStore, String securityDomain) {
|
public PlainSASL(SecurityStore securityStore, String securityDomain, RemotingConnection remotingConnection) {
|
||||||
this.securityStore = securityStore;
|
this.securityStore = securityStore;
|
||||||
this.securityDomain = securityDomain;
|
this.securityDomain = securityDomain;
|
||||||
|
this.remotingConnection = remotingConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean authenticate(String user, String password) {
|
protected boolean authenticate(String user, String password) {
|
||||||
if (securityStore.isSecurityEnabled()) {
|
if (securityStore.isSecurityEnabled()) {
|
||||||
try {
|
try {
|
||||||
securityStore.authenticate(user, password, null, securityDomain);
|
securityStore.authenticate(user, password, remotingConnection, securityDomain);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.artemis.protocol.amqp.broker;
|
package org.apache.activemq.artemis.protocol.amqp.broker;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnection;
|
||||||
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
|
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
|
||||||
import org.apache.activemq.artemis.protocol.amqp.sasl.AnonymousServerSASL;
|
import org.apache.activemq.artemis.protocol.amqp.sasl.AnonymousServerSASL;
|
||||||
import org.apache.activemq.artemis.protocol.amqp.sasl.GSSAPIServerSASL;
|
import org.apache.activemq.artemis.protocol.amqp.sasl.GSSAPIServerSASL;
|
||||||
|
@ -32,7 +33,7 @@ public class AMQPConnectionCallbackTest {
|
||||||
public void getServerSASLOnlyAllowedMechs() throws Exception {
|
public void getServerSASLOnlyAllowedMechs() throws Exception {
|
||||||
ProtonProtocolManager protonProtocolManager = new ProtonProtocolManager(new ProtonProtocolManagerFactory(), null, null, null);
|
ProtonProtocolManager protonProtocolManager = new ProtonProtocolManager(new ProtonProtocolManagerFactory(), null, null, null);
|
||||||
protonProtocolManager.setSaslMechanisms(new String[]{PlainSASL.NAME});
|
protonProtocolManager.setSaslMechanisms(new String[]{PlainSASL.NAME});
|
||||||
AMQPConnectionCallback connectionCallback = new AMQPConnectionCallback(protonProtocolManager, null, null, new ActiveMQServerImpl());
|
AMQPConnectionCallback connectionCallback = new AMQPConnectionCallback(protonProtocolManager, new InVMConnection(1, null, null, null), null, new ActiveMQServerImpl());
|
||||||
assertEquals(1, connectionCallback.getSaslMechanisms().length);
|
assertEquals(1, connectionCallback.getSaslMechanisms().length);
|
||||||
for (String mech: connectionCallback.getSaslMechanisms()) {
|
for (String mech: connectionCallback.getSaslMechanisms()) {
|
||||||
assertNotNull(connectionCallback.getServerSASL(mech));
|
assertNotNull(connectionCallback.getServerSASL(mech));
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class MQTTConnection implements RemotingConnection {
|
||||||
private final List<FailureListener> failureListeners = new CopyOnWriteArrayList<>();
|
private final List<FailureListener> failureListeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
private final List<CloseListener> closeListeners = new CopyOnWriteArrayList<>();
|
private final List<CloseListener> closeListeners = new CopyOnWriteArrayList<>();
|
||||||
|
private Subject subject;
|
||||||
|
|
||||||
public MQTTConnection(Connection transportConnection) throws Exception {
|
public MQTTConnection(Connection transportConnection) throws Exception {
|
||||||
this.transportConnection = transportConnection;
|
this.transportConnection = transportConnection;
|
||||||
|
@ -258,6 +259,16 @@ public class MQTTConnection implements RemotingConnection {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuditSubject(Subject subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject getAuditSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getSubject() {
|
public Subject getSubject() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -39,6 +39,7 @@ import io.netty.handler.codec.mqtt.MqttUnsubAckMessage;
|
||||||
import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage;
|
import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
|
import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,6 +99,10 @@ public class MQTTProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
connection.dataReceived();
|
connection.dataReceived();
|
||||||
|
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
AuditLogger.setRemoteAddress(connection.getRemoteAddress());
|
||||||
|
}
|
||||||
|
|
||||||
MQTTUtil.logMessage(session.getState(), message, true);
|
MQTTUtil.logMessage(session.getState(), message, true);
|
||||||
|
|
||||||
if (this.protocolManager.invokeIncoming(message, this.connection) != null) {
|
if (this.protocolManager.invokeIncoming(message, this.connection) != null) {
|
||||||
|
|
|
@ -80,6 +80,7 @@ import org.apache.activemq.artemis.core.transaction.ResourceManager;
|
||||||
import org.apache.activemq.artemis.core.transaction.Transaction;
|
import org.apache.activemq.artemis.core.transaction.Transaction;
|
||||||
import org.apache.activemq.artemis.core.transaction.TransactionOperationAbstract;
|
import org.apache.activemq.artemis.core.transaction.TransactionOperationAbstract;
|
||||||
import org.apache.activemq.artemis.core.transaction.TransactionPropertyIndexes;
|
import org.apache.activemq.artemis.core.transaction.TransactionPropertyIndexes;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection;
|
import org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
|
import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
|
||||||
import org.apache.activemq.artemis.spi.core.remoting.Connection;
|
import org.apache.activemq.artemis.spi.core.remoting.Connection;
|
||||||
|
@ -305,6 +306,10 @@ public class OpenWireConnection extends AbstractRemotingConnection implements Se
|
||||||
try {
|
try {
|
||||||
recoverOperationContext();
|
recoverOperationContext();
|
||||||
|
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
AuditLogger.setRemoteAddress(getRemoteAddress());
|
||||||
|
}
|
||||||
|
|
||||||
boolean responseRequired = command.isResponseRequired();
|
boolean responseRequired = command.isResponseRequired();
|
||||||
int commandId = command.getCommandId();
|
int commandId = command.getCommandId();
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ public final class StompConnection implements RemotingConnection {
|
||||||
private final ScheduledExecutorService scheduledExecutorService;
|
private final ScheduledExecutorService scheduledExecutorService;
|
||||||
|
|
||||||
private final ExecutorFactory executorFactory;
|
private final ExecutorFactory executorFactory;
|
||||||
|
private Subject subject;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupportReconnect() {
|
public boolean isSupportReconnect() {
|
||||||
|
@ -855,6 +856,16 @@ public final class StompConnection implements RemotingConnection {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuditSubject(Subject subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject getAuditSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getSubject() {
|
public Subject getSubject() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||||
import org.apache.activemq.artemis.core.server.ServerSession;
|
import org.apache.activemq.artemis.core.server.ServerSession;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.AbstractProtocolManager;
|
import org.apache.activemq.artemis.spi.core.protocol.AbstractProtocolManager;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
|
import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
|
import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
|
||||||
|
@ -154,6 +155,9 @@ public class StompProtocolManager extends AbstractProtocolManager<StompFrame, St
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
AuditLogger.setRemoteAddress(connection.getRemoteAddress());
|
||||||
|
}
|
||||||
conn.logFrame(request, true);
|
conn.logFrame(request, true);
|
||||||
if (invokeInterceptors(this.incomingInterceptors, request, conn) != null) {
|
if (invokeInterceptors(this.incomingInterceptors, request, conn) != null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -846,9 +846,7 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String createAddress(String name, String routingTypes) throws Exception {
|
public String createAddress(String name, String routingTypes) throws Exception {
|
||||||
if (AuditLogger.isEnabled()) {
|
|
||||||
AuditLogger.createAddress(this.server, name, routingTypes);
|
|
||||||
}
|
|
||||||
checkStarted();
|
checkStarted();
|
||||||
|
|
||||||
clearIO();
|
clearIO();
|
||||||
|
@ -859,8 +857,15 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
}
|
}
|
||||||
final AddressInfo addressInfo = new AddressInfo(new SimpleString(name), set);
|
final AddressInfo addressInfo = new AddressInfo(new SimpleString(name), set);
|
||||||
if (server.addAddressInfo(addressInfo)) {
|
if (server.addAddressInfo(addressInfo)) {
|
||||||
return AddressInfoTextFormatter.Long.format(addressInfo, new StringBuilder()).toString();
|
String result = AddressInfoTextFormatter.Long.format(addressInfo, new StringBuilder()).toString();
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.createAddressSuccess(name, routingTypes);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.createAddressFailure(name, routingTypes);
|
||||||
|
}
|
||||||
throw ActiveMQMessageBundle.BUNDLE.addressAlreadyExists(addressInfo.getName());
|
throw ActiveMQMessageBundle.BUNDLE.addressAlreadyExists(addressInfo.getName());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -870,9 +875,7 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String updateAddress(String name, String routingTypes) throws Exception {
|
public String updateAddress(String name, String routingTypes) throws Exception {
|
||||||
if (AuditLogger.isEnabled()) {
|
|
||||||
AuditLogger.updateAddress(this.server, name, routingTypes);
|
|
||||||
}
|
|
||||||
checkStarted();
|
checkStarted();
|
||||||
|
|
||||||
clearIO();
|
clearIO();
|
||||||
|
@ -888,8 +891,14 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!server.updateAddressInfo(SimpleString.toSimpleString(name), routingTypeSet)) {
|
if (!server.updateAddressInfo(SimpleString.toSimpleString(name), routingTypeSet)) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.updateAddressFailure(name, routingTypes);
|
||||||
|
}
|
||||||
throw ActiveMQMessageBundle.BUNDLE.addressDoesNotExist(SimpleString.toSimpleString(name));
|
throw ActiveMQMessageBundle.BUNDLE.addressDoesNotExist(SimpleString.toSimpleString(name));
|
||||||
}
|
}
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.updateAddressSuccess(name, routingTypes);
|
||||||
|
}
|
||||||
return AddressInfoTextFormatter.Long.format(server.getAddressInfo(SimpleString.toSimpleString(name)), new StringBuilder()).toString();
|
return AddressInfoTextFormatter.Long.format(server.getAddressInfo(SimpleString.toSimpleString(name)), new StringBuilder()).toString();
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
|
@ -904,15 +913,18 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAddress(String name, boolean force) throws Exception {
|
public void deleteAddress(String name, boolean force) throws Exception {
|
||||||
if (AuditLogger.isEnabled()) {
|
|
||||||
AuditLogger.deleteAddress(this.server, name, force);
|
|
||||||
}
|
|
||||||
checkStarted();
|
checkStarted();
|
||||||
|
|
||||||
clearIO();
|
clearIO();
|
||||||
try {
|
try {
|
||||||
server.removeAddressInfo(new SimpleString(name), null, force);
|
server.removeAddressInfo(new SimpleString(name), null, force);
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.deleteAddressSuccess(name);
|
||||||
|
}
|
||||||
} catch (ActiveMQException e) {
|
} catch (ActiveMQException e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.deleteAddressFailure(name);
|
||||||
|
}
|
||||||
throw new IllegalStateException(e.getMessage());
|
throw new IllegalStateException(e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
|
@ -1203,8 +1215,14 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
.setAutoDeleteMessageCount(autoDeleteMessageCount)
|
.setAutoDeleteMessageCount(autoDeleteMessageCount)
|
||||||
.setAutoCreateAddress(autoCreateAddress)
|
.setAutoCreateAddress(autoCreateAddress)
|
||||||
.setRingSize(ringSize));
|
.setRingSize(ringSize));
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.createQueueSuccess( name, address, routingType);
|
||||||
|
}
|
||||||
return QueueTextFormatter.Long.format(queue, new StringBuilder()).toString();
|
return QueueTextFormatter.Long.format(queue, new StringBuilder()).toString();
|
||||||
} catch (ActiveMQException e) {
|
} catch (ActiveMQException e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.createQueueFailure( name, address, routingType);
|
||||||
|
}
|
||||||
throw new IllegalStateException(e.getMessage());
|
throw new IllegalStateException(e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
|
@ -1353,8 +1371,15 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
try {
|
try {
|
||||||
final Queue queue = server.updateQueue(name, routingType != null ? RoutingType.valueOf(routingType) : null, filter, maxConsumers, purgeOnNoConsumers, exclusive, groupRebalance, groupBuckets, groupFirstKey, nonDestructive, consumersBeforeDispatch, delayBeforeDispatch, user);
|
final Queue queue = server.updateQueue(name, routingType != null ? RoutingType.valueOf(routingType) : null, filter, maxConsumers, purgeOnNoConsumers, exclusive, groupRebalance, groupBuckets, groupFirstKey, nonDestructive, consumersBeforeDispatch, delayBeforeDispatch, user);
|
||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.updateQueueFailure(name, routingType);
|
||||||
|
}
|
||||||
throw ActiveMQMessageBundle.BUNDLE.noSuchQueue(new SimpleString(name));
|
throw ActiveMQMessageBundle.BUNDLE.noSuchQueue(new SimpleString(name));
|
||||||
}
|
}
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.updateQueueSuccess(name, routingType);
|
||||||
|
}
|
||||||
|
|
||||||
return QueueTextFormatter.Long.format(queue, new StringBuilder()).toString();
|
return QueueTextFormatter.Long.format(queue, new StringBuilder()).toString();
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
|
@ -1490,7 +1515,17 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
||||||
clearIO();
|
clearIO();
|
||||||
try {
|
try {
|
||||||
SimpleString queueName = new SimpleString(name);
|
SimpleString queueName = new SimpleString(name);
|
||||||
|
try {
|
||||||
server.destroyQueue(queueName, null, !removeConsumers, removeConsumers, autoDeleteAddress);
|
server.destroyQueue(queueName, null, !removeConsumers, removeConsumers, autoDeleteAddress);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.destroyQueueFailure(name);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.destroyQueueSuccess(name);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,6 +181,16 @@ public class ManagementRemotingConnection implements RemotingConnection {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuditSubject(Subject subject) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject getAuditSubject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject getSubject() {
|
public Subject getSubject() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1000,7 +1000,19 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
|
||||||
try {
|
try {
|
||||||
Filter filter = FilterImpl.createFilter(filterStr);
|
Filter filter = FilterImpl.createFilter(filterStr);
|
||||||
|
|
||||||
return queue.deleteMatchingReferences(flushLimit, filter);
|
int removed = 0;
|
||||||
|
try {
|
||||||
|
removed = queue.deleteMatchingReferences(flushLimit, filter);
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.removeMessagesSuccess(removed, queue.getName().toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.removeMessagesFailure(queue.getName().toString());
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
}
|
}
|
||||||
|
@ -1194,8 +1206,15 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
|
||||||
AuditLogger.sendMessage(queue, null, headers, type, body, durable, user, "****");
|
AuditLogger.sendMessage(queue, null, headers, type, body, durable, user, "****");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return sendMessage(queue.getAddress(), server, headers, type, body, durable, user, password, queue.getID());
|
String s = sendMessage(queue.getAddress(), server, headers, type, body, durable, user, password, queue.getID());
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.sendMessageSuccess(queue.getName().toString(), user);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.sendMessageFailure(queue.getName().toString(), user);
|
||||||
|
}
|
||||||
throw new IllegalStateException(e.getMessage());
|
throw new IllegalStateException(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1338,8 +1357,17 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
|
||||||
checkStarted();
|
checkStarted();
|
||||||
|
|
||||||
clearIO();
|
clearIO();
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
queue.pause();
|
queue.pause();
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.pauseQueueSuccess(queue.getName().toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.pauseQueueFailure(queue.getName().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
}
|
}
|
||||||
|
@ -1354,8 +1382,17 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
|
||||||
checkStarted();
|
checkStarted();
|
||||||
|
|
||||||
clearIO();
|
clearIO();
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
queue.pause(persist);
|
queue.pause(persist);
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.pauseQueueSuccess(queue.getName().toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.pauseQueueFailure(queue.getName().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
}
|
}
|
||||||
|
@ -1368,8 +1405,18 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
|
||||||
checkStarted();
|
checkStarted();
|
||||||
|
|
||||||
clearIO();
|
clearIO();
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
queue.resume();
|
queue.resume();
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.resumeQueueSuccess(queue.getName().toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.resumeQueueFailure(queue.getName().toString());
|
||||||
|
}
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
}
|
}
|
||||||
|
@ -1425,9 +1472,15 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
|
||||||
|
|
||||||
CompositeData[] rc = new CompositeData[c.size()];
|
CompositeData[] rc = new CompositeData[c.size()];
|
||||||
c.toArray(rc);
|
c.toArray(rc);
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.browseMessagesSuccess(queue.getName().toString(), c.size());
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} catch (ActiveMQException e) {
|
} catch (ActiveMQException e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.browseMessagesFailure(queue.getName().toString());
|
||||||
|
}
|
||||||
throw new IllegalStateException(e.getMessage());
|
throw new IllegalStateException(e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
|
@ -1467,9 +1520,15 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
|
||||||
|
|
||||||
CompositeData[] rc = new CompositeData[c.size()];
|
CompositeData[] rc = new CompositeData[c.size()];
|
||||||
c.toArray(rc);
|
c.toArray(rc);
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.browseMessagesSuccess(queue.getName().toString(), currentPageSize);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} catch (ActiveMQException e) {
|
} catch (ActiveMQException e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.browseMessagesFailure(queue.getName().toString());
|
||||||
|
}
|
||||||
throw new IllegalStateException(e.getMessage());
|
throw new IllegalStateException(e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
blockOnIO();
|
blockOnIO();
|
||||||
|
|
|
@ -95,6 +95,7 @@ import org.apache.activemq.artemis.core.server.BindingQueryResult;
|
||||||
import org.apache.activemq.artemis.core.server.LargeServerMessage;
|
import org.apache.activemq.artemis.core.server.LargeServerMessage;
|
||||||
import org.apache.activemq.artemis.core.server.QueueQueryResult;
|
import org.apache.activemq.artemis.core.server.QueueQueryResult;
|
||||||
import org.apache.activemq.artemis.core.server.ServerSession;
|
import org.apache.activemq.artemis.core.server.ServerSession;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.EmbedMessageUtil;
|
import org.apache.activemq.artemis.spi.core.protocol.EmbedMessageUtil;
|
||||||
import org.apache.activemq.artemis.spi.core.remoting.Connection;
|
import org.apache.activemq.artemis.spi.core.remoting.Connection;
|
||||||
import org.apache.activemq.artemis.utils.SimpleFuture;
|
import org.apache.activemq.artemis.utils.SimpleFuture;
|
||||||
|
@ -264,6 +265,10 @@ public class ServerSessionPacketHandler implements ChannelHandler {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("ServerSessionPacketHandler::handlePacket," + packet);
|
logger.trace("ServerSessionPacketHandler::handlePacket," + packet);
|
||||||
}
|
}
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
AuditLogger.setRemoteAddress(remotingConnection.getRemoteAddress());
|
||||||
|
AuditLogger.setCurrentCaller(remotingConnection.getAuditSubject());
|
||||||
|
}
|
||||||
final byte type = packet.getType();
|
final byte type = packet.getType();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SESS_SEND: {
|
case SESS_SEND: {
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.activemq.artemis.core.server.ServerProducer;
|
||||||
import org.apache.activemq.artemis.core.server.ServerSession;
|
import org.apache.activemq.artemis.core.server.ServerSession;
|
||||||
import org.apache.activemq.artemis.core.server.impl.ServerProducerImpl;
|
import org.apache.activemq.artemis.core.server.impl.ServerProducerImpl;
|
||||||
import org.apache.activemq.artemis.core.version.Version;
|
import org.apache.activemq.artemis.core.version.Version;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,6 +83,11 @@ public class ActiveMQPacketHandler implements ChannelHandler {
|
||||||
public void handlePacket(final Packet packet) {
|
public void handlePacket(final Packet packet) {
|
||||||
byte type = packet.getType();
|
byte type = packet.getType();
|
||||||
|
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
AuditLogger.setRemoteAddress(connection.getRemoteAddress());
|
||||||
|
AuditLogger.setCurrentCaller(connection.getAuditSubject());
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PacketImpl.CREATESESSION: {
|
case PacketImpl.CREATESESSION: {
|
||||||
CreateSessionMessage request = (CreateSessionMessage) packet;
|
CreateSessionMessage request = (CreateSessionMessage) packet;
|
||||||
|
|
|
@ -61,6 +61,7 @@ import org.apache.activemq.artemis.core.server.management.ManagementService;
|
||||||
import org.apache.activemq.artemis.core.server.management.Notification;
|
import org.apache.activemq.artemis.core.server.management.Notification;
|
||||||
import org.apache.activemq.artemis.core.transaction.Transaction;
|
import org.apache.activemq.artemis.core.transaction.Transaction;
|
||||||
import org.apache.activemq.artemis.core.transaction.impl.TransactionImpl;
|
import org.apache.activemq.artemis.core.transaction.impl.TransactionImpl;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
|
import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
|
||||||
import org.apache.activemq.artemis.spi.core.remoting.ReadyListener;
|
import org.apache.activemq.artemis.spi.core.remoting.ReadyListener;
|
||||||
import org.apache.activemq.artemis.utils.FutureLatch;
|
import org.apache.activemq.artemis.utils.FutureLatch;
|
||||||
|
@ -489,6 +490,9 @@ public class ServerConsumerImpl implements ServerConsumer, ReadyListener {
|
||||||
try {
|
try {
|
||||||
Message message = reference.getMessage();
|
Message message = reference.getMessage();
|
||||||
|
|
||||||
|
if (AuditLogger.isMessageEnabled()) {
|
||||||
|
AuditLogger.coreConsumeMessage(getQueueName().toString());
|
||||||
|
}
|
||||||
if (server.hasBrokerMessagePlugins()) {
|
if (server.hasBrokerMessagePlugins()) {
|
||||||
server.callBrokerMessagePlugins(plugin -> plugin.beforeDeliver(this, reference));
|
server.callBrokerMessagePlugins(plugin -> plugin.beforeDeliver(this, reference));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1749,7 +1749,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
|
||||||
boolean noAutoCreateQueue,
|
boolean noAutoCreateQueue,
|
||||||
RoutingContext routingContext) throws Exception {
|
RoutingContext routingContext) throws Exception {
|
||||||
if (AuditLogger.isMessageEnabled()) {
|
if (AuditLogger.isMessageEnabled()) {
|
||||||
AuditLogger.coreSendMessage(this, getUsername(), tx, messageParameter, direct, noAutoCreateQueue, routingContext);
|
AuditLogger.coreSendMessage(getUsername(), routingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Message message = LargeServerMessageImpl.checkLargeMessage(messageParameter, storageManager);
|
final Message message = LargeServerMessageImpl.checkLargeMessage(messageParameter, storageManager);
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.artemis.core.server.management;
|
package org.apache.activemq.artemis.core.server.management;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
@ -57,6 +59,16 @@ public class ArtemisMBeanServerBuilder extends MBeanServerBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
//if this is invoked via jolokia the address will be set by the filter
|
||||||
|
//if not we can deduct it from RMI or it must be internal
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled() && AuditLogger.getRemoteAddress() == null) {
|
||||||
|
String name = Thread.currentThread().getName();
|
||||||
|
String url = "internal";
|
||||||
|
if (name.startsWith("RMI TCP Connection")) {
|
||||||
|
url = name.substring(name.indexOf('-') + 1);
|
||||||
|
}
|
||||||
|
AuditLogger.setRemoteAddress(url);
|
||||||
|
}
|
||||||
if (guarded.contains(method.getName())) {
|
if (guarded.contains(method.getName())) {
|
||||||
if (ArtemisMBeanServerBuilder.guard == null) {
|
if (ArtemisMBeanServerBuilder.guard == null) {
|
||||||
throw new IllegalStateException("ArtemisMBeanServerBuilder not initialized");
|
throw new IllegalStateException("ArtemisMBeanServerBuilder not initialized");
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
package org.apache.activemq.artemis.core.server.management;
|
package org.apache.activemq.artemis.core.server.management;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
|
|
||||||
import javax.management.Attribute;
|
import javax.management.Attribute;
|
||||||
import javax.management.AttributeList;
|
import javax.management.AttributeList;
|
||||||
import javax.management.JMException;
|
import javax.management.JMException;
|
||||||
|
@ -121,6 +123,9 @@ public class ArtemisMBeanServerGuard implements InvocationHandler {
|
||||||
if (currentUserHasRole(role))
|
if (currentUserHasRole(role))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.objectInvokedFailure(objectName, operationName);
|
||||||
|
}
|
||||||
throw new SecurityException("Insufficient roles/credentials for operation");
|
throw new SecurityException("Insufficient roles/credentials for operation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.artemis.core.server.management;
|
package org.apache.activemq.artemis.core.server.management;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
|
|
||||||
import javax.management.remote.JMXAuthenticator;
|
import javax.management.remote.JMXAuthenticator;
|
||||||
import javax.security.auth.Subject;
|
import javax.security.auth.Subject;
|
||||||
import javax.security.auth.callback.Callback;
|
import javax.security.auth.callback.Callback;
|
||||||
|
@ -41,8 +43,9 @@ public class JaasAuthenticator implements JMXAuthenticator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subject authenticate(final Object credentials) throws SecurityException {
|
public Subject authenticate(final Object credentials) throws SecurityException {
|
||||||
try {
|
|
||||||
Subject subject = new Subject();
|
Subject subject = new Subject();
|
||||||
|
try {
|
||||||
|
|
||||||
LoginContext loginContext = new LoginContext(realm, subject, new CallbackHandler() {
|
LoginContext loginContext = new LoginContext(realm, subject, new CallbackHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -70,8 +73,14 @@ public class JaasAuthenticator implements JMXAuthenticator {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
loginContext.login();
|
loginContext.login();
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.userSuccesfullyLoggedInAudit(subject);
|
||||||
|
}
|
||||||
return subject;
|
return subject;
|
||||||
} catch (LoginException e) {
|
} catch (LoginException e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.userFailedLoggedInAudit(subject, e.getMessage());
|
||||||
|
}
|
||||||
throw new SecurityException("Authentication failed", e);
|
throw new SecurityException("Authentication failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
|
||||||
import org.apache.activemq.artemis.core.security.CheckType;
|
import org.apache.activemq.artemis.core.security.CheckType;
|
||||||
import org.apache.activemq.artemis.core.security.Role;
|
import org.apache.activemq.artemis.core.security.Role;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
|
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
|
||||||
import org.apache.activemq.artemis.spi.core.security.jaas.JaasCallbackHandler;
|
import org.apache.activemq.artemis.spi.core.security.jaas.JaasCallbackHandler;
|
||||||
import org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal;
|
import org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal;
|
||||||
|
@ -193,7 +194,20 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager4 {
|
||||||
} else {
|
} else {
|
||||||
lc = new LoginContext(configurationName, null, new JaasCallbackHandler(user, password, remotingConnection), configuration);
|
lc = new LoginContext(configurationName, null, new JaasCallbackHandler(user, password, remotingConnection), configuration);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
lc.login();
|
lc.login();
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled() && remotingConnection != null) {
|
||||||
|
remotingConnection.setAuditSubject(lc.getSubject());
|
||||||
|
}
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.userSuccesfullyLoggedInAudit(lc.getSubject());
|
||||||
|
}
|
||||||
|
} catch (LoginException e) {
|
||||||
|
if (AuditLogger.isResourceLoggingEnabled()) {
|
||||||
|
AuditLogger.userFailedLoggedInAudit(lc.getSubject(), e.getMessage());
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
return lc.getSubject();
|
return lc.getSubject();
|
||||||
} finally {
|
} finally {
|
||||||
if (thisLoader != currentLoader) {
|
if (thisLoader != currentLoader) {
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.activemq.artemis.spi.core.security.jaas;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
|
|
||||||
|
import javax.security.auth.Subject;
|
||||||
|
import javax.security.auth.spi.LoginModule;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is only to support auditlogging
|
||||||
|
* */
|
||||||
|
public interface AuditLoginModule extends LoginModule {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need this because if authentication fails at the web layer then there is no way to access the unauthenticated
|
||||||
|
* subject as it is removed and the session destroyed and never gets as far as the broker
|
||||||
|
* */
|
||||||
|
default void registerFailureForAudit(String name) {
|
||||||
|
Subject subject = new Subject();
|
||||||
|
subject.getPrincipals().add(new UserPrincipal(name));
|
||||||
|
AuditLogger.setCurrentCaller(subject);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ import javax.security.auth.callback.CallbackHandler;
|
||||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
import javax.security.auth.login.FailedLoginException;
|
import javax.security.auth.login.FailedLoginException;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
|
||||||
import javax.security.cert.X509Certificate;
|
import javax.security.cert.X509Certificate;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
@ -37,7 +36,7 @@ import org.jboss.logging.Logger;
|
||||||
* Allows for subclasses to define methods used to verify user certificates and
|
* Allows for subclasses to define methods used to verify user certificates and
|
||||||
* find user roles. Uses CertificateCallbacks to retrieve certificates.
|
* find user roles. Uses CertificateCallbacks to retrieve certificates.
|
||||||
*/
|
*/
|
||||||
public abstract class CertificateLoginModule extends PropertiesLoader implements LoginModule {
|
public abstract class CertificateLoginModule extends PropertiesLoader implements AuditLoginModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(CertificateLoginModule.class);
|
private static final Logger logger = Logger.getLogger(CertificateLoginModule.class);
|
||||||
|
|
||||||
|
@ -116,6 +115,7 @@ public abstract class CertificateLoginModule extends PropertiesLoader implements
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
|
registerFailureForAudit(username);
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import javax.security.auth.callback.Callback;
|
||||||
import javax.security.auth.callback.CallbackHandler;
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
|
||||||
import javax.security.cert.X509Certificate;
|
import javax.security.cert.X509Certificate;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
@ -35,7 +34,7 @@ import org.jboss.logging.Logger;
|
||||||
/**
|
/**
|
||||||
* A LoginModule that propagates TLS certificates subject DN as a UserPrincipal.
|
* A LoginModule that propagates TLS certificates subject DN as a UserPrincipal.
|
||||||
*/
|
*/
|
||||||
public class ExternalCertificateLoginModule implements LoginModule {
|
public class ExternalCertificateLoginModule implements AuditLoginModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ExternalCertificateLoginModule.class);
|
private static final Logger logger = Logger.getLogger(ExternalCertificateLoginModule.class);
|
||||||
|
|
||||||
|
@ -90,6 +89,7 @@ public class ExternalCertificateLoginModule implements LoginModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
|
registerFailureForAudit(userName);
|
||||||
clear();
|
clear();
|
||||||
logger.debug("abort");
|
logger.debug("abort");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import javax.security.auth.callback.CallbackHandler;
|
||||||
import javax.security.auth.callback.PasswordCallback;
|
import javax.security.auth.callback.PasswordCallback;
|
||||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -37,7 +36,7 @@ import org.jboss.logging.Logger;
|
||||||
* Useful for unauthenticated communication channels being used in the
|
* Useful for unauthenticated communication channels being used in the
|
||||||
* same broker as authenticated ones.
|
* same broker as authenticated ones.
|
||||||
*/
|
*/
|
||||||
public class GuestLoginModule implements LoginModule {
|
public class GuestLoginModule implements AuditLoginModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(GuestLoginModule.class);
|
private static final Logger logger = Logger.getLogger(GuestLoginModule.class);
|
||||||
|
|
||||||
|
@ -114,7 +113,7 @@ public class GuestLoginModule implements LoginModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
|
registerFailureForAudit(GUEST_USER);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
logger.debug("abort");
|
logger.debug("abort");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import javax.security.auth.callback.PasswordCallback;
|
||||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
import javax.security.auth.login.FailedLoginException;
|
import javax.security.auth.login.FailedLoginException;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -35,7 +34,7 @@ import java.util.Set;
|
||||||
import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
|
import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class InVMLoginModule implements LoginModule {
|
public class InVMLoginModule implements AuditLoginModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(InVMLoginModule.class);
|
private static final Logger logger = Logger.getLogger(InVMLoginModule.class);
|
||||||
|
|
||||||
|
@ -126,6 +125,7 @@ public class InVMLoginModule implements LoginModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
|
registerFailureForAudit(user);
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
logger.debug("abort");
|
logger.debug("abort");
|
||||||
|
|
|
@ -23,7 +23,6 @@ import javax.security.auth.callback.Callback;
|
||||||
import javax.security.auth.callback.CallbackHandler;
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -33,7 +32,7 @@ import java.util.Map;
|
||||||
/**
|
/**
|
||||||
* populate a subject with kerberos credential from the handler
|
* populate a subject with kerberos credential from the handler
|
||||||
*/
|
*/
|
||||||
public class Krb5LoginModule implements LoginModule {
|
public class Krb5LoginModule implements AuditLoginModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Krb5LoginModule.class);
|
private static final Logger logger = Logger.getLogger(Krb5LoginModule.class);
|
||||||
|
|
||||||
|
@ -41,6 +40,7 @@ public class Krb5LoginModule implements LoginModule {
|
||||||
private final List<Principal> principals = new LinkedList<>();
|
private final List<Principal> principals = new LinkedList<>();
|
||||||
private CallbackHandler callbackHandler;
|
private CallbackHandler callbackHandler;
|
||||||
private boolean loginSucceeded;
|
private boolean loginSucceeded;
|
||||||
|
private Principal principal;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(Subject subject,
|
public void initialize(Subject subject,
|
||||||
|
@ -58,7 +58,7 @@ public class Krb5LoginModule implements LoginModule {
|
||||||
callbacks[0] = new Krb5Callback();
|
callbacks[0] = new Krb5Callback();
|
||||||
try {
|
try {
|
||||||
callbackHandler.handle(callbacks);
|
callbackHandler.handle(callbacks);
|
||||||
Principal principal = ((Krb5Callback)callbacks[0]).getPeerPrincipal();
|
principal = ((Krb5Callback)callbacks[0]).getPeerPrincipal();
|
||||||
if (principal != null) {
|
if (principal != null) {
|
||||||
principals.add(principal);
|
principals.add(principal);
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,7 @@ public class Krb5LoginModule implements LoginModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
|
registerFailureForAudit(principal != null ? principal.getName() : null);
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
logger.debug("abort");
|
logger.debug("abort");
|
||||||
|
@ -99,6 +100,7 @@ public class Krb5LoginModule implements LoginModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clear() {
|
private void clear() {
|
||||||
|
principal = null;
|
||||||
loginSucceeded = false;
|
loginSucceeded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
import javax.security.auth.login.FailedLoginException;
|
import javax.security.auth.login.FailedLoginException;
|
||||||
import javax.security.auth.login.LoginContext;
|
import javax.security.auth.login.LoginContext;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
@ -62,7 +61,7 @@ import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||||
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
|
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class LDAPLoginModule implements LoginModule {
|
public class LDAPLoginModule implements AuditLoginModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(LDAPLoginModule.class);
|
private static final Logger logger = Logger.getLogger(LDAPLoginModule.class);
|
||||||
|
|
||||||
|
@ -243,6 +242,7 @@ public class LDAPLoginModule implements LoginModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
|
registerFailureForAudit(username);
|
||||||
clear();
|
clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import javax.security.auth.callback.PasswordCallback;
|
||||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||||
import javax.security.auth.login.FailedLoginException;
|
import javax.security.auth.login.FailedLoginException;
|
||||||
import javax.security.auth.login.LoginException;
|
import javax.security.auth.login.LoginException;
|
||||||
import javax.security.auth.spi.LoginModule;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -36,7 +35,7 @@ import org.apache.activemq.artemis.utils.HashProcessor;
|
||||||
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
|
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class PropertiesLoginModule extends PropertiesLoader implements LoginModule {
|
public class PropertiesLoginModule extends PropertiesLoader implements AuditLoginModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(PropertiesLoginModule.class);
|
private static final Logger logger = Logger.getLogger(PropertiesLoginModule.class);
|
||||||
|
|
||||||
|
@ -144,6 +143,7 @@ public class PropertiesLoginModule extends PropertiesLoader implements LoginModu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean abort() throws LoginException {
|
public boolean abort() throws LoginException {
|
||||||
|
registerFailureForAudit(user);
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.activemq.artemis.component;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
|
import org.eclipse.jetty.server.Request;
|
||||||
|
import org.eclipse.jetty.server.Response;
|
||||||
|
|
||||||
|
import javax.security.auth.Subject;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This filter intercepts the login and audits its results
|
||||||
|
* */
|
||||||
|
public class AuthenticationFilter implements Filter {
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||||
|
filterChain.doFilter(servletRequest, servletResponse);
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
int status = ((Response) servletResponse).getStatus();
|
||||||
|
//status 200 means that the user has been authenticated, anything else must be a failure
|
||||||
|
if (status == 200) {
|
||||||
|
HttpSession session = ((Request) servletRequest).getSession();
|
||||||
|
AuditLogger.userSuccesfullyLoggedInAudit(session != null ? (Subject) session.getAttribute("subject") : null);
|
||||||
|
} else {
|
||||||
|
AuditLogger.userFailedLoggedInAudit("" + status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.activemq.artemis.component;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.logs.AuditLogger;
|
||||||
|
import org.eclipse.jetty.server.Request;
|
||||||
|
|
||||||
|
import javax.security.auth.Subject;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This intercepts all calls made via jolokia
|
||||||
|
* */
|
||||||
|
public class JolokiaFilter implements Filter {
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||||
|
/*
|
||||||
|
* this is the only place we can catch the remote address of the calling console client thru Jolokia.
|
||||||
|
* We set the address on the calling thread which will end up in JMX audit logging
|
||||||
|
* */
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled() && servletRequest != null) {
|
||||||
|
String remoteHost = servletRequest.getRemoteHost();
|
||||||
|
AuditLogger.setRemoteAddress(remoteHost + ":" + servletRequest.getRemotePort());
|
||||||
|
}
|
||||||
|
filterChain.doFilter(servletRequest, servletResponse);
|
||||||
|
/*
|
||||||
|
* This is the only place we can get access to the authenticated subject on invocations after the login has happened.
|
||||||
|
* we set the subject for audit logging
|
||||||
|
* */
|
||||||
|
if (AuditLogger.isAnyLoggingEnabled()) {
|
||||||
|
try {
|
||||||
|
HttpSession session = ((Request) servletRequest).getSession();
|
||||||
|
Subject subject = (Subject) session.getAttribute("subject");
|
||||||
|
AuditLogger.setCurrentCaller(subject);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
//best effort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import java.net.URI;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -44,10 +45,13 @@ import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
import org.eclipse.jetty.server.handler.HandlerList;
|
import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
import org.eclipse.jetty.server.handler.RequestLogHandler;
|
import org.eclipse.jetty.server.handler.RequestLogHandler;
|
||||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||||
|
import org.eclipse.jetty.servlet.FilterHolder;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import javax.servlet.DispatcherType;
|
||||||
|
|
||||||
public class WebServerComponent implements ExternalComponent {
|
public class WebServerComponent implements ExternalComponent {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(WebServerComponent.class);
|
private static final Logger logger = Logger.getLogger(WebServerComponent.class);
|
||||||
|
@ -303,6 +307,9 @@ public class WebServerComponent implements ExternalComponent {
|
||||||
} else {
|
} else {
|
||||||
webapp.setContextPath("/" + url);
|
webapp.setContextPath("/" + url);
|
||||||
}
|
}
|
||||||
|
//add the filters needed for audit logging
|
||||||
|
webapp.addFilter(new FilterHolder(JolokiaFilter.class), "/*", EnumSet.of(DispatcherType.INCLUDE, DispatcherType.REQUEST));
|
||||||
|
webapp.addFilter(new FilterHolder(AuthenticationFilter.class), "/auth/login/*", EnumSet.of(DispatcherType.REQUEST));
|
||||||
|
|
||||||
webapp.setWar(warDirectory.resolve(warFile).toString());
|
webapp.setWar(warDirectory.resolve(warFile).toString());
|
||||||
handlers.addHandler(webapp);
|
handlers.addHandler(webapp);
|
||||||
|
|
|
@ -5,7 +5,7 @@ configurable via the `logging.properties` file found in the
|
||||||
configuration directories. This is configured by Default to log to both
|
configuration directories. This is configured by Default to log to both
|
||||||
the console and to a file.
|
the console and to a file.
|
||||||
|
|
||||||
There are 8 loggers available which are as follows:
|
There are 9 loggers available which are as follows:
|
||||||
|
|
||||||
Logger | Description
|
Logger | Description
|
||||||
---|---
|
---|---
|
||||||
|
@ -16,6 +16,7 @@ org.apache.activemq.artemis.journal|Logs Journal calls
|
||||||
org.apache.activemq.artemis.jms|Logs JMS calls
|
org.apache.activemq.artemis.jms|Logs JMS calls
|
||||||
org.apache.activemq.artemis.integration.bootstrap|Logs bootstrap calls
|
org.apache.activemq.artemis.integration.bootstrap|Logs bootstrap calls
|
||||||
org.apache.activemq.audit.base|audit log. Disabled by default
|
org.apache.activemq.audit.base|audit log. Disabled by default
|
||||||
|
org.apache.activemq.audit.resource|resource audit log. Disabled by default
|
||||||
org.apache.activemq.audit.message|message audit log. Disabled by default
|
org.apache.activemq.audit.message|message audit log. Disabled by default
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,17 +89,25 @@ formatter.PATTERN.properties=pattern
|
||||||
formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} %-5p [%c] %s%E%n
|
formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} %-5p [%c] %s%E%n
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuring Audit Log
|
## Configuring Audit Logging
|
||||||
|
|
||||||
The 2 audit loggers can be enabled to record some important operations like
|
There are 3 audit loggers that can be enabled separately and audit sifferent types of events, these are:
|
||||||
create/delete queues. By default this logger is disabled. The configuration
|
|
||||||
(logging.properties) for audit log is like this by default:
|
1. Base logger: This is a highly verbose logger that will capture most events that occur on JMX beans
|
||||||
|
2. Resource logger: This logs creation, updates and deletion of resources such as Addresses and Queues and also authentication, the main purpose of this is to track console activity and access to broker.
|
||||||
|
3. Message logger: this logs message production and consumption of messages and will have a potentially negatibve affect on performance
|
||||||
|
|
||||||
|
These are disabled by default in the logging.properties configuration file:
|
||||||
|
|
||||||
```$xslt
|
```$xslt
|
||||||
logger.org.apache.activemq.audit.base.level=ERROR
|
logger.org.apache.activemq.audit.base.level=ERROR
|
||||||
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
||||||
|
|
||||||
|
logger.org.apache.activemq.audit.resource.level=ERROR
|
||||||
|
logger.org.apache.activemq.audit.resource.handlers=AUDIT_FILE
|
||||||
|
logger.org.apache.activemq.audit.resource.useParentHandlers=false
|
||||||
|
|
||||||
logger.org.apache.activemq.audit.message.level=ERROR
|
logger.org.apache.activemq.audit.message.level=ERROR
|
||||||
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
||||||
|
@ -110,21 +119,33 @@ To enable the audit log change the above level to INFO, like this:
|
||||||
logger.org.apache.activemq.audit.base.level=INFO
|
logger.org.apache.activemq.audit.base.level=INFO
|
||||||
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
||||||
|
|
||||||
logger.org.apache.activemq.audit.message.level=INFO
|
|
||||||
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
|
||||||
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
The 2 audit loggers can be disable/enable separately. The second logger
|
The 3 audit loggers can be disable/enabled separately.
|
||||||
(org.apache.activemq.audit.message) audits messages in 'hot path'
|
|
||||||
(code path that is very sensitive to performance, e.g. sending messages).
|
|
||||||
Turn on this audit logger may affect the performance.
|
|
||||||
|
|
||||||
Once enabled, all audit records are written into a separate log
|
Once enabled, all audit records are written into a separate log
|
||||||
file (by default audit.log).
|
file (by default audit.log).
|
||||||
|
|
||||||
|
### Logging the clients remote address
|
||||||
|
|
||||||
|
It is possible to configure the audit loggers to log the remote address of any calling clients either through normal
|
||||||
|
clients or through the console and JMX. This is configured by enabling a specific login module in the login config file.
|
||||||
|
```$xslt
|
||||||
|
org.apache.activemq.artemis.spi.core.security.jaas.AuditLoginModule optional
|
||||||
|
debug=false;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
> **Note:**
|
||||||
|
>
|
||||||
|
> This needs to be the first entry in the login.config file
|
||||||
|
|
||||||
|
> **Note:**
|
||||||
|
>
|
||||||
|
> This login module does no authentication, it is used only to catch client information through which ever path a client takes
|
||||||
|
|
||||||
|
|
||||||
## Use Custom Handlers
|
## Use Custom Handlers
|
||||||
|
|
||||||
To use a different handler than the built-in ones, you either pick one from
|
To use a different handler than the built-in ones, you either pick one from
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Additional logger names to configure (root logger is always configured)
|
||||||
|
# Root logger option
|
||||||
|
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message,org.apache.activemq.audit.resource
|
||||||
|
|
||||||
|
# Root logger level
|
||||||
|
logger.level=INFO
|
||||||
|
# ActiveMQ Artemis logger levels
|
||||||
|
logger.org.apache.activemq.artemis.core.server.level=INFO
|
||||||
|
logger.org.apache.activemq.artemis.journal.level=INFO
|
||||||
|
logger.org.apache.activemq.artemis.utils.level=INFO
|
||||||
|
logger.org.apache.activemq.artemis.jms.level=INFO
|
||||||
|
logger.org.apache.activemq.artemis.integration.bootstrap.level=INFO
|
||||||
|
logger.org.eclipse.jetty.level=WARN
|
||||||
|
# Root logger handlers
|
||||||
|
logger.handlers=FILE,CONSOLE
|
||||||
|
|
||||||
|
# to enable audit change the level to INFO
|
||||||
|
logger.org.apache.activemq.audit.base.level=INFO
|
||||||
|
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
||||||
|
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
||||||
|
|
||||||
|
logger.org.apache.activemq.audit.resource.level=INFO
|
||||||
|
logger.org.apache.activemq.audit.resource.handlers=AUDIT_FILE
|
||||||
|
logger.org.apache.activemq.audit.resource.useParentHandlers=false
|
||||||
|
|
||||||
|
logger.org.apache.activemq.audit.message.level=INFO
|
||||||
|
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
||||||
|
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
||||||
|
|
||||||
|
# Console handler configuration
|
||||||
|
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
|
||||||
|
handler.CONSOLE.properties=autoFlush
|
||||||
|
handler.CONSOLE.level=DEBUG
|
||||||
|
handler.CONSOLE.autoFlush=true
|
||||||
|
handler.CONSOLE.formatter=PATTERN
|
||||||
|
|
||||||
|
# File handler configuration
|
||||||
|
handler.FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
|
||||||
|
handler.FILE.level=DEBUG
|
||||||
|
handler.FILE.properties=suffix,append,autoFlush,fileName
|
||||||
|
handler.FILE.suffix=.yyyy-MM-dd
|
||||||
|
handler.FILE.append=true
|
||||||
|
handler.FILE.autoFlush=true
|
||||||
|
handler.FILE.fileName=${artemis.instance}/log/artemis.log
|
||||||
|
handler.FILE.formatter=PATTERN
|
||||||
|
|
||||||
|
# Formatter pattern configuration
|
||||||
|
formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
|
||||||
|
formatter.PATTERN.properties=pattern
|
||||||
|
formatter.PATTERN.pattern=%d %-5p [%c] %s%E%n
|
||||||
|
|
||||||
|
#Audit logger
|
||||||
|
handler.AUDIT_FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
|
||||||
|
handler.AUDIT_FILE.level=INFO
|
||||||
|
handler.AUDIT_FILE.properties=suffix,append,autoFlush,fileName
|
||||||
|
handler.AUDIT_FILE.suffix=.yyyy-MM-dd
|
||||||
|
handler.AUDIT_FILE.append=true
|
||||||
|
handler.AUDIT_FILE.autoFlush=true
|
||||||
|
handler.AUDIT_FILE.fileName=${artemis.instance}/log/audit.log
|
||||||
|
handler.AUDIT_FILE.formatter=AUDIT_PATTERN
|
||||||
|
|
||||||
|
formatter.AUDIT_PATTERN=org.jboss.logmanager.formatters.PatternFormatter
|
||||||
|
formatter.AUDIT_PATTERN.properties=pattern
|
||||||
|
formatter.AUDIT_PATTERN.pattern=%d [AUDIT](%t) %s%E%n
|
|
@ -267,6 +267,48 @@
|
||||||
</args>
|
</args>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<id>create-createAuditLogging</id>
|
||||||
|
<goals>
|
||||||
|
<goal>create</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<configuration>${basedir}/target/classes/servers/audit-logging</configuration>
|
||||||
|
<noWeb>false</noWeb>
|
||||||
|
<allowAnonymous>true</allowAnonymous>
|
||||||
|
<user>admin</user>
|
||||||
|
<password>admin</password>
|
||||||
|
<instance>${basedir}/target/audit-logging</instance>
|
||||||
|
<args>
|
||||||
|
<!-- this is needed to run the server remotely -->
|
||||||
|
<arg>--java-options</arg>
|
||||||
|
<arg>-Djava.rmi.server.hostname=localhost</arg>
|
||||||
|
<!--<arg>-Djava.rmi.server.hostname=localhost -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005</arg>-->
|
||||||
|
</args>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<id>create-createAuditLogging2</id>
|
||||||
|
<goals>
|
||||||
|
<goal>create</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<configuration>${basedir}/target/classes/servers/audit-logging2</configuration>
|
||||||
|
<noWeb>false</noWeb>
|
||||||
|
<allowAnonymous>true</allowAnonymous>
|
||||||
|
<user>admin</user>
|
||||||
|
<password>admin</password>
|
||||||
|
<instance>${basedir}/target/audit-logging2</instance>
|
||||||
|
<args>
|
||||||
|
<!-- this is needed to run the server remotely -->
|
||||||
|
<arg>--java-options</arg>
|
||||||
|
<arg>-Djava.rmi.server.hostname=localhost</arg>
|
||||||
|
<!--<arg>-Djava.rmi.server.hostname=localhost -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005</arg>-->
|
||||||
|
</args>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>test-compile</phase>
|
<phase>test-compile</phase>
|
||||||
<id>create-jmx-failback</id>
|
<id>create-jmx-failback</id>
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<configuration xmlns="urn:activemq"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
|
||||||
|
|
||||||
|
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="urn:activemq:core ">
|
||||||
|
|
||||||
|
<name>0.0.0.0</name>
|
||||||
|
|
||||||
|
<persistence-enabled>true</persistence-enabled>
|
||||||
|
|
||||||
|
<!-- this could be ASYNCIO or NIO
|
||||||
|
-->
|
||||||
|
<journal-type>NIO</journal-type>
|
||||||
|
|
||||||
|
<paging-directory>./data/paging</paging-directory>
|
||||||
|
|
||||||
|
<bindings-directory>./data/bindings</bindings-directory>
|
||||||
|
|
||||||
|
<journal-directory>./data/journal</journal-directory>
|
||||||
|
|
||||||
|
<large-messages-directory>./data/large-messages</large-messages-directory>
|
||||||
|
|
||||||
|
<journal-datasync>true</journal-datasync>
|
||||||
|
|
||||||
|
<journal-min-files>2</journal-min-files>
|
||||||
|
|
||||||
|
<journal-pool-files>-1</journal-pool-files>
|
||||||
|
|
||||||
|
<message-expiry-scan-period>1000</message-expiry-scan-period>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
You can verify the network health of a particular NIC by specifying the <network-check-NIC> element.
|
||||||
|
<network-check-NIC>theNicName</network-check-NIC>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Use this to use an HTTP server to validate the network
|
||||||
|
<network-check-URL-list>http://www.apache.org</network-check-URL-list> -->
|
||||||
|
|
||||||
|
<!-- <network-check-period>10000</network-check-period> -->
|
||||||
|
<!-- <network-check-timeout>1000</network-check-timeout> -->
|
||||||
|
|
||||||
|
<!-- this is a comma separated list, no spaces, just DNS or IPs
|
||||||
|
it should accept IPV6
|
||||||
|
|
||||||
|
Warning: Make sure you understand your network topology as this is meant to validate if your network is valid.
|
||||||
|
Using IPs that could eventually disappear or be partially visible may defeat the purpose.
|
||||||
|
You can use a list of multiple IPs, and if any successful ping will make the server OK to continue running -->
|
||||||
|
<!-- <network-check-list>10.0.0.1</network-check-list> -->
|
||||||
|
|
||||||
|
<!-- use this to customize the ping used for ipv4 addresses -->
|
||||||
|
<!-- <network-check-ping-command>ping -c 1 -t %d %s</network-check-ping-command> -->
|
||||||
|
|
||||||
|
<!-- use this to customize the ping used for ipv6 addresses -->
|
||||||
|
<!-- <network-check-ping6-command>ping6 -c 1 %2$s</network-check-ping6-command> -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
|
||||||
|
<disk-scan-period>5000</disk-scan-period>
|
||||||
|
|
||||||
|
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols
|
||||||
|
that won't support flow control. -->
|
||||||
|
<max-disk-usage>90</max-disk-usage>
|
||||||
|
|
||||||
|
<!-- the system will enter into page mode once you hit this limit.
|
||||||
|
This is an estimate in bytes of how much the messages are using in memory
|
||||||
|
|
||||||
|
The system will use half of the available memory (-Xmx) by default for the global-max-size.
|
||||||
|
You may specify a different value here if you need to customize it to your needs.
|
||||||
|
|
||||||
|
<global-max-size>100Mb</global-max-size>
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<acceptors>
|
||||||
|
|
||||||
|
<!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
|
||||||
|
<!-- useKQueue means: it will use Netty kqueue if you are on a system (MacOS) that supports it -->
|
||||||
|
<!-- amqpCredits: The number of credits sent to AMQP producers -->
|
||||||
|
<!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
|
||||||
|
|
||||||
|
<!-- Acceptor for every supported protocol -->
|
||||||
|
<acceptor name="artemis">tcp://localhost:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;useKQueue;amqpCredits=1000;amqpLowCredits=300</acceptor>
|
||||||
|
|
||||||
|
<!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
|
||||||
|
<acceptor name="amqp">tcp://localhost:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;useKQueue=true;amqpCredits=1000;amqpLowCredits=300</acceptor>
|
||||||
|
|
||||||
|
<!-- STOMP Acceptor. -->
|
||||||
|
<acceptor name="stomp">tcp://localhost:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;useKQueue=true</acceptor>
|
||||||
|
|
||||||
|
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
|
||||||
|
<acceptor name="hornetq">tcp://localhost:5445?protocols=HORNETQ,STOMP;useEpoll=true;useKQueue=true</acceptor>
|
||||||
|
|
||||||
|
<!-- MQTT Acceptor -->
|
||||||
|
<acceptor name="mqtt">tcp://localhost:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true;useKQueue=true</acceptor>
|
||||||
|
|
||||||
|
</acceptors>
|
||||||
|
|
||||||
|
|
||||||
|
<security-settings>
|
||||||
|
<security-setting match="#">
|
||||||
|
<permission type="createNonDurableQueue" roles="guest"/>
|
||||||
|
<permission type="deleteNonDurableQueue" roles="guest"/>
|
||||||
|
<permission type="createDurableQueue" roles="guest"/>
|
||||||
|
<permission type="deleteDurableQueue" roles="guest"/>
|
||||||
|
<permission type="createAddress" roles="guest"/>
|
||||||
|
<permission type="deleteAddress" roles="guest"/>
|
||||||
|
<permission type="consume" roles="guest"/>
|
||||||
|
<permission type="browse" roles="guest"/>
|
||||||
|
<permission type="send" roles="guest"/>
|
||||||
|
<!-- we need this otherwise ./artemis data imp wouldn't work -->
|
||||||
|
<permission type="manage" roles="guest"/>
|
||||||
|
</security-setting>
|
||||||
|
</security-settings>
|
||||||
|
|
||||||
|
<address-settings>
|
||||||
|
<!-- if you define auto-create on certain queues, management has to be auto-create -->
|
||||||
|
<address-setting match="activemq.management#">
|
||||||
|
<dead-letter-address>DLQ</dead-letter-address>
|
||||||
|
<expiry-address>ExpiryQueue</expiry-address>
|
||||||
|
<redelivery-delay>0</redelivery-delay>
|
||||||
|
<!-- with -1 only the global-max-size is in use for limiting -->
|
||||||
|
<max-size-bytes>-1</max-size-bytes>
|
||||||
|
<message-counter-history-day-limit>10</message-counter-history-day-limit>
|
||||||
|
<address-full-policy>PAGE</address-full-policy>
|
||||||
|
<auto-create-queues>true</auto-create-queues>
|
||||||
|
<auto-create-addresses>true</auto-create-addresses>
|
||||||
|
<auto-create-jms-queues>true</auto-create-jms-queues>
|
||||||
|
<auto-create-jms-topics>true</auto-create-jms-topics>
|
||||||
|
</address-setting>
|
||||||
|
<!--default for catch all-->
|
||||||
|
<address-setting match="#">
|
||||||
|
<dead-letter-address>DLQ</dead-letter-address>
|
||||||
|
<expiry-address>ExpiryQueue</expiry-address>
|
||||||
|
<redelivery-delay>0</redelivery-delay>
|
||||||
|
<!-- with -1 only the global-max-size is in use for limiting -->
|
||||||
|
<max-size-bytes>-1</max-size-bytes>
|
||||||
|
<message-counter-history-day-limit>10</message-counter-history-day-limit>
|
||||||
|
<address-full-policy>PAGE</address-full-policy>
|
||||||
|
<auto-create-queues>true</auto-create-queues>
|
||||||
|
<auto-create-addresses>true</auto-create-addresses>
|
||||||
|
<auto-create-jms-queues>true</auto-create-jms-queues>
|
||||||
|
<auto-create-jms-topics>true</auto-create-jms-topics>
|
||||||
|
</address-setting>
|
||||||
|
</address-settings>
|
||||||
|
|
||||||
|
<addresses>
|
||||||
|
<address name="myQ">
|
||||||
|
<anycast>
|
||||||
|
<queue name="myQ"/>
|
||||||
|
</anycast>
|
||||||
|
</address>
|
||||||
|
<address name="DLQ">
|
||||||
|
<anycast>
|
||||||
|
<queue name="DLQ" />
|
||||||
|
</anycast>
|
||||||
|
</address>
|
||||||
|
<address name="ExpiryQueue">
|
||||||
|
<anycast>
|
||||||
|
<queue name="ExpiryQueue" />
|
||||||
|
</anycast>
|
||||||
|
</address>
|
||||||
|
|
||||||
|
</addresses>
|
||||||
|
|
||||||
|
</core>
|
||||||
|
</configuration>
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
# Additional logger names to configure (root logger is always configured)
|
# Additional logger names to configure (root logger is always configured)
|
||||||
# Root logger option
|
# Root logger option
|
||||||
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message
|
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message,org.apache.activemq.audit.resource
|
||||||
|
|
||||||
# Root logger level
|
# Root logger level
|
||||||
logger.level=INFO
|
logger.level=INFO
|
||||||
|
@ -31,13 +31,17 @@ logger.org.eclipse.jetty.level=WARN
|
||||||
# Root logger handlers
|
# Root logger handlers
|
||||||
logger.handlers=FILE,CONSOLE
|
logger.handlers=FILE,CONSOLE
|
||||||
|
|
||||||
logger.org.apache.activemq.audit.base.level=INFO
|
logger.org.apache.activemq.audit.base.level=ERROR
|
||||||
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
logger.org.apache.activemq.audit.base.useParentHandlers=false
|
||||||
|
|
||||||
logger.org.apache.activemq.audit.message.level=ERROR
|
logger.org.apache.activemq.audit.message.level=ERROR
|
||||||
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
logger.org.apache.activemq.audit.message.useParentHandlers=
|
||||||
|
|
||||||
|
logger.org.apache.activemq.audit.resource.level=INFO
|
||||||
|
logger.org.apache.activemq.audit.resource.handlers=AUDIT_FILE
|
||||||
|
logger.org.apache.activemq.audit.resource.useParentHandlers=false
|
||||||
|
|
||||||
# Console handler configuration
|
# Console handler configuration
|
||||||
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
|
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
|
||||||
|
@ -53,7 +57,7 @@ handler.FILE.properties=suffix,append,autoFlush,fileName
|
||||||
handler.FILE.suffix=.yyyy-MM-dd
|
handler.FILE.suffix=.yyyy-MM-dd
|
||||||
handler.FILE.append=true
|
handler.FILE.append=true
|
||||||
handler.FILE.autoFlush=true
|
handler.FILE.autoFlush=true
|
||||||
handler.FILE.fileName=target/artemis.log
|
handler.FILE.fileName=../log/artemis.log
|
||||||
handler.FILE.formatter=PATTERN
|
handler.FILE.formatter=PATTERN
|
||||||
|
|
||||||
# Formatter pattern configuration
|
# Formatter pattern configuration
|
||||||
|
@ -68,7 +72,7 @@ handler.AUDIT_FILE.properties=suffix,append,autoFlush,fileName
|
||||||
handler.AUDIT_FILE.suffix=.yyyy-MM-dd
|
handler.AUDIT_FILE.suffix=.yyyy-MM-dd
|
||||||
handler.AUDIT_FILE.append=true
|
handler.AUDIT_FILE.append=true
|
||||||
handler.AUDIT_FILE.autoFlush=true
|
handler.AUDIT_FILE.autoFlush=true
|
||||||
handler.AUDIT_FILE.fileName=target/audit.log
|
handler.AUDIT_FILE.fileName=../log/audit.log
|
||||||
handler.AUDIT_FILE.formatter=AUDIT_PATTERN
|
handler.AUDIT_FILE.formatter=AUDIT_PATTERN
|
||||||
|
|
||||||
formatter.AUDIT_PATTERN=org.jboss.logmanager.formatters.PatternFormatter
|
formatter.AUDIT_PATTERN=org.jboss.logmanager.formatters.PatternFormatter
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
activemq {
|
||||||
|
org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
|
||||||
|
debug=false
|
||||||
|
reload=true
|
||||||
|
org.apache.activemq.jaas.properties.user="artemis-users.properties"
|
||||||
|
org.apache.activemq.jaas.properties.role="artemis-roles.properties";
|
||||||
|
|
||||||
|
org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
|
||||||
|
debug=false
|
||||||
|
org.apache.activemq.jaas.guest.user="guest"
|
||||||
|
org.apache.activemq.jaas.guest.role="guest";
|
||||||
|
};
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
<management-context xmlns="http://activemq.org/schema">
|
||||||
|
<connector connector-port="10099" connector-host="localhost"/>
|
||||||
|
<authorisation>
|
||||||
|
<whitelist>
|
||||||
|
<entry domain="hawtio"/>
|
||||||
|
</whitelist>
|
||||||
|
<default-access>
|
||||||
|
<access method="list*" roles="guest"/>
|
||||||
|
<access method="get*" roles="guest"/>
|
||||||
|
<access method="is*" roles="guest"/>
|
||||||
|
<access method="set*" roles="guest"/>
|
||||||
|
<access method="*" roles="guest"/>
|
||||||
|
</default-access>
|
||||||
|
<role-access>
|
||||||
|
<match domain="org.apache.activemq.artemis">
|
||||||
|
<access method="list*" roles="guest"/>
|
||||||
|
<access method="get*" roles="guest"/>
|
||||||
|
<access method="is*" roles="guest"/>
|
||||||
|
<access method="set*" roles="guest"/>
|
||||||
|
<access method="*" roles="guest"/>
|
||||||
|
</match>
|
||||||
|
<!--example of how to configure a specific object-->
|
||||||
|
<!--<match domain="org.apache.activemq.artemis" key="subcomponent=queues">
|
||||||
|
<access method="list*" roles="view,update,amq"/>
|
||||||
|
<access method="get*" roles="view,update,amq"/>
|
||||||
|
<access method="is*" roles="view,update,amq"/>
|
||||||
|
<access method="set*" roles="update,amq"/>
|
||||||
|
<access method="*" roles="amq"/>
|
||||||
|
</match>-->
|
||||||
|
</role-access>
|
||||||
|
</authorisation>
|
||||||
|
</management-context>
|
|
@ -0,0 +1,190 @@
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<configuration xmlns="urn:activemq"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
|
||||||
|
|
||||||
|
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="urn:activemq:core ">
|
||||||
|
|
||||||
|
<name>0.0.0.0</name>
|
||||||
|
|
||||||
|
<persistence-enabled>true</persistence-enabled>
|
||||||
|
|
||||||
|
<!-- this could be ASYNCIO or NIO
|
||||||
|
-->
|
||||||
|
<journal-type>NIO</journal-type>
|
||||||
|
|
||||||
|
<paging-directory>./data/paging</paging-directory>
|
||||||
|
|
||||||
|
<bindings-directory>./data/bindings</bindings-directory>
|
||||||
|
|
||||||
|
<journal-directory>./data/journal</journal-directory>
|
||||||
|
|
||||||
|
<large-messages-directory>./data/large-messages</large-messages-directory>
|
||||||
|
|
||||||
|
<journal-datasync>true</journal-datasync>
|
||||||
|
|
||||||
|
<journal-min-files>2</journal-min-files>
|
||||||
|
|
||||||
|
<journal-pool-files>-1</journal-pool-files>
|
||||||
|
|
||||||
|
<message-expiry-scan-period>1000</message-expiry-scan-period>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
You can verify the network health of a particular NIC by specifying the <network-check-NIC> element.
|
||||||
|
<network-check-NIC>theNicName</network-check-NIC>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Use this to use an HTTP server to validate the network
|
||||||
|
<network-check-URL-list>http://www.apache.org</network-check-URL-list> -->
|
||||||
|
|
||||||
|
<!-- <network-check-period>10000</network-check-period> -->
|
||||||
|
<!-- <network-check-timeout>1000</network-check-timeout> -->
|
||||||
|
|
||||||
|
<!-- this is a comma separated list, no spaces, just DNS or IPs
|
||||||
|
it should accept IPV6
|
||||||
|
|
||||||
|
Warning: Make sure you understand your network topology as this is meant to validate if your network is valid.
|
||||||
|
Using IPs that could eventually disappear or be partially visible may defeat the purpose.
|
||||||
|
You can use a list of multiple IPs, and if any successful ping will make the server OK to continue running -->
|
||||||
|
<!-- <network-check-list>10.0.0.1</network-check-list> -->
|
||||||
|
|
||||||
|
<!-- use this to customize the ping used for ipv4 addresses -->
|
||||||
|
<!-- <network-check-ping-command>ping -c 1 -t %d %s</network-check-ping-command> -->
|
||||||
|
|
||||||
|
<!-- use this to customize the ping used for ipv6 addresses -->
|
||||||
|
<!-- <network-check-ping6-command>ping6 -c 1 %2$s</network-check-ping6-command> -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
|
||||||
|
<disk-scan-period>5000</disk-scan-period>
|
||||||
|
|
||||||
|
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols
|
||||||
|
that won't support flow control. -->
|
||||||
|
<max-disk-usage>90</max-disk-usage>
|
||||||
|
|
||||||
|
<!-- the system will enter into page mode once you hit this limit.
|
||||||
|
This is an estimate in bytes of how much the messages are using in memory
|
||||||
|
|
||||||
|
The system will use half of the available memory (-Xmx) by default for the global-max-size.
|
||||||
|
You may specify a different value here if you need to customize it to your needs.
|
||||||
|
|
||||||
|
<global-max-size>100Mb</global-max-size>
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<acceptors>
|
||||||
|
|
||||||
|
<!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
|
||||||
|
<!-- useKQueue means: it will use Netty kqueue if you are on a system (MacOS) that supports it -->
|
||||||
|
<!-- amqpCredits: The number of credits sent to AMQP producers -->
|
||||||
|
<!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
|
||||||
|
|
||||||
|
<!-- Acceptor for every supported protocol -->
|
||||||
|
<acceptor name="artemis">tcp://localhost:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;useKQueue;amqpCredits=1000;amqpLowCredits=300</acceptor>
|
||||||
|
|
||||||
|
<!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
|
||||||
|
<acceptor name="amqp">tcp://localhost:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;useKQueue=true;amqpCredits=1000;amqpLowCredits=300</acceptor>
|
||||||
|
|
||||||
|
<!-- STOMP Acceptor. -->
|
||||||
|
<acceptor name="stomp">tcp://localhost:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;useKQueue=true</acceptor>
|
||||||
|
|
||||||
|
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
|
||||||
|
<acceptor name="hornetq">tcp://localhost:5445?protocols=HORNETQ,STOMP;useEpoll=true;useKQueue=true</acceptor>
|
||||||
|
|
||||||
|
<!-- MQTT Acceptor -->
|
||||||
|
<acceptor name="mqtt">tcp://localhost:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true;useKQueue=true</acceptor>
|
||||||
|
|
||||||
|
</acceptors>
|
||||||
|
|
||||||
|
|
||||||
|
<security-settings>
|
||||||
|
<security-setting match="#">
|
||||||
|
<permission type="createNonDurableQueue" roles="guest"/>
|
||||||
|
<permission type="deleteNonDurableQueue" roles=""/>
|
||||||
|
<permission type="createDurableQueue" roles="guest"/>
|
||||||
|
<permission type="deleteDurableQueue" roles="guest"/>
|
||||||
|
<permission type="createAddress" roles="guest"/>
|
||||||
|
<permission type="deleteAddress" roles="guest"/>
|
||||||
|
<permission type="consume" roles="guest"/>
|
||||||
|
<permission type="browse" roles="guest"/>
|
||||||
|
<permission type="send" roles="guest"/>
|
||||||
|
<!-- we need this otherwise ./artemis data imp wouldn't work -->
|
||||||
|
<permission type="manage" roles="guest"/>
|
||||||
|
</security-setting>
|
||||||
|
</security-settings>
|
||||||
|
|
||||||
|
<address-settings>
|
||||||
|
<!-- if you define auto-create on certain queues, management has to be auto-create -->
|
||||||
|
<address-setting match="activemq.management#">
|
||||||
|
<dead-letter-address>DLQ</dead-letter-address>
|
||||||
|
<expiry-address>ExpiryQueue</expiry-address>
|
||||||
|
<redelivery-delay>0</redelivery-delay>
|
||||||
|
<!-- with -1 only the global-max-size is in use for limiting -->
|
||||||
|
<max-size-bytes>-1</max-size-bytes>
|
||||||
|
<message-counter-history-day-limit>10</message-counter-history-day-limit>
|
||||||
|
<address-full-policy>PAGE</address-full-policy>
|
||||||
|
<auto-create-queues>true</auto-create-queues>
|
||||||
|
<auto-create-addresses>true</auto-create-addresses>
|
||||||
|
<auto-create-jms-queues>true</auto-create-jms-queues>
|
||||||
|
<auto-create-jms-topics>true</auto-create-jms-topics>
|
||||||
|
</address-setting>
|
||||||
|
<!--default for catch all-->
|
||||||
|
<address-setting match="#">
|
||||||
|
<dead-letter-address>DLQ</dead-letter-address>
|
||||||
|
<expiry-address>ExpiryQueue</expiry-address>
|
||||||
|
<redelivery-delay>0</redelivery-delay>
|
||||||
|
<!-- with -1 only the global-max-size is in use for limiting -->
|
||||||
|
<max-size-bytes>-1</max-size-bytes>
|
||||||
|
<message-counter-history-day-limit>10</message-counter-history-day-limit>
|
||||||
|
<address-full-policy>PAGE</address-full-policy>
|
||||||
|
<auto-create-queues>true</auto-create-queues>
|
||||||
|
<auto-create-addresses>true</auto-create-addresses>
|
||||||
|
<auto-create-jms-queues>true</auto-create-jms-queues>
|
||||||
|
<auto-create-jms-topics>true</auto-create-jms-topics>
|
||||||
|
</address-setting>
|
||||||
|
</address-settings>
|
||||||
|
|
||||||
|
<addresses>
|
||||||
|
<address name="myQ">
|
||||||
|
<anycast>
|
||||||
|
<queue name="myQ"/>
|
||||||
|
</anycast>
|
||||||
|
</address>
|
||||||
|
<address name="DLQ">
|
||||||
|
<anycast>
|
||||||
|
<queue name="DLQ" />
|
||||||
|
</anycast>
|
||||||
|
</address>
|
||||||
|
<address name="ExpiryQueue">
|
||||||
|
<anycast>
|
||||||
|
<queue name="ExpiryQueue" />
|
||||||
|
</anycast>
|
||||||
|
</address>
|
||||||
|
|
||||||
|
</addresses>
|
||||||
|
|
||||||
|
</core>
|
||||||
|
</configuration>
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
# Additional logger names to configure (root logger is always configured)
|
# Additional logger names to configure (root logger is always configured)
|
||||||
# Root logger option
|
# Root logger option
|
||||||
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message
|
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message,org.apache.activemq.audit.resource
|
||||||
|
|
||||||
# Root logger level
|
# Root logger level
|
||||||
logger.level=INFO
|
logger.level=INFO
|
||||||
|
@ -37,7 +37,11 @@ logger.org.apache.activemq.audit.base.useParentHandlers=false
|
||||||
|
|
||||||
logger.org.apache.activemq.audit.message.level=INFO
|
logger.org.apache.activemq.audit.message.level=INFO
|
||||||
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
|
||||||
logger.org.apache.activemq.audit.message.useParentHandlers=false
|
logger.org.apache.activemq.audit.message.useParentHandlers=
|
||||||
|
|
||||||
|
logger.org.apache.activemq.audit.resource.level=ERROR
|
||||||
|
logger.org.apache.activemq.audit.resource.handlers=AUDIT_FILE
|
||||||
|
logger.org.apache.activemq.audit.resource.useParentHandlers=false
|
||||||
|
|
||||||
# Console handler configuration
|
# Console handler configuration
|
||||||
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
|
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
|
||||||
|
@ -53,7 +57,7 @@ handler.FILE.properties=suffix,append,autoFlush,fileName
|
||||||
handler.FILE.suffix=.yyyy-MM-dd
|
handler.FILE.suffix=.yyyy-MM-dd
|
||||||
handler.FILE.append=true
|
handler.FILE.append=true
|
||||||
handler.FILE.autoFlush=true
|
handler.FILE.autoFlush=true
|
||||||
handler.FILE.fileName=target/artemis.log
|
handler.FILE.fileName=../log/artemis.log
|
||||||
handler.FILE.formatter=PATTERN
|
handler.FILE.formatter=PATTERN
|
||||||
|
|
||||||
# Formatter pattern configuration
|
# Formatter pattern configuration
|
||||||
|
@ -62,13 +66,13 @@ formatter.PATTERN.properties=pattern
|
||||||
formatter.PATTERN.pattern=%d %-5p [%c] %s%E%n
|
formatter.PATTERN.pattern=%d %-5p [%c] %s%E%n
|
||||||
|
|
||||||
#Audit logger
|
#Audit logger
|
||||||
handler.AUDIT_FILE.level=DEBUG
|
handler.AUDIT_FILE.level=INFO
|
||||||
handler.AUDIT_FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
|
handler.AUDIT_FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
|
||||||
handler.AUDIT_FILE.properties=suffix,append,autoFlush,fileName
|
handler.AUDIT_FILE.properties=suffix,append,autoFlush,fileName
|
||||||
handler.AUDIT_FILE.suffix=.yyyy-MM-dd
|
handler.AUDIT_FILE.suffix=.yyyy-MM-dd
|
||||||
handler.AUDIT_FILE.append=true
|
handler.AUDIT_FILE.append=true
|
||||||
handler.AUDIT_FILE.autoFlush=true
|
handler.AUDIT_FILE.autoFlush=true
|
||||||
handler.AUDIT_FILE.fileName=target/audit.log
|
handler.AUDIT_FILE.fileName=../log/audit.log
|
||||||
handler.AUDIT_FILE.formatter=AUDIT_PATTERN
|
handler.AUDIT_FILE.formatter=AUDIT_PATTERN
|
||||||
|
|
||||||
formatter.AUDIT_PATTERN=org.jboss.logmanager.formatters.PatternFormatter
|
formatter.AUDIT_PATTERN=org.jboss.logmanager.formatters.PatternFormatter
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
activemq {
|
||||||
|
org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
|
||||||
|
debug=false
|
||||||
|
reload=true
|
||||||
|
org.apache.activemq.jaas.properties.user="artemis-users.properties"
|
||||||
|
org.apache.activemq.jaas.properties.role="artemis-roles.properties";
|
||||||
|
|
||||||
|
org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
|
||||||
|
debug=false
|
||||||
|
org.apache.activemq.jaas.guest.user="guest"
|
||||||
|
org.apache.activemq.jaas.guest.role="guest";
|
||||||
|
};
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
<management-context xmlns="http://activemq.org/schema">
|
||||||
|
<connector connector-port="10099" connector-host="localhost"/>
|
||||||
|
<authorisation>
|
||||||
|
<whitelist>
|
||||||
|
<entry domain="hawtio"/>
|
||||||
|
</whitelist>
|
||||||
|
<default-access>
|
||||||
|
<access method="list*" roles="guest"/>
|
||||||
|
<access method="get*" roles="guest"/>
|
||||||
|
<access method="is*" roles="guest"/>
|
||||||
|
<access method="set*" roles="guest"/>
|
||||||
|
<access method="*" roles="guest"/>
|
||||||
|
</default-access>
|
||||||
|
<role-access>
|
||||||
|
<match domain="org.apache.activemq.artemis">
|
||||||
|
<access method="list*" roles="guest"/>
|
||||||
|
<access method="get*" roles="guest"/>
|
||||||
|
<access method="is*" roles="guest"/>
|
||||||
|
<access method="set*" roles="guest"/>
|
||||||
|
<access method="*" roles="guest"/>
|
||||||
|
</match>
|
||||||
|
<!--example of how to configure a specific object-->
|
||||||
|
<!--<match domain="org.apache.activemq.artemis" key="subcomponent=queues">
|
||||||
|
<access method="list*" roles="view,update,amq"/>
|
||||||
|
<access method="get*" roles="view,update,amq"/>
|
||||||
|
<access method="is*" roles="view,update,amq"/>
|
||||||
|
<access method="set*" roles="update,amq"/>
|
||||||
|
<access method="*" roles="amq"/>
|
||||||
|
</match>-->
|
||||||
|
</role-access>
|
||||||
|
</authorisation>
|
||||||
|
</management-context>
|
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.activemq.artemis.tests.smoke.logging;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||||
|
import org.apache.activemq.artemis.api.core.RoutingType;
|
||||||
|
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||||
|
import org.apache.activemq.artemis.api.core.client.ClientProducer;
|
||||||
|
import org.apache.activemq.artemis.api.core.client.ClientSession;
|
||||||
|
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
|
||||||
|
import org.apache.activemq.artemis.api.core.client.ServerLocator;
|
||||||
|
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl;
|
||||||
|
import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
|
||||||
|
import org.apache.activemq.artemis.api.core.management.QueueControl;
|
||||||
|
import org.apache.activemq.artemis.tests.smoke.common.SmokeTestBase;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.management.MBeanServerConnection;
|
||||||
|
import javax.management.MBeanServerInvocationHandler;
|
||||||
|
import javax.management.openmbean.CompositeData;
|
||||||
|
import javax.management.remote.JMXConnector;
|
||||||
|
import javax.management.remote.JMXConnectorFactory;
|
||||||
|
import javax.management.remote.JMXServiceURL;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class AuditLoggerResourceTest extends SmokeTestBase {
|
||||||
|
|
||||||
|
private static final File auditLog = new File("target/audit-logging/log/audit.log");
|
||||||
|
|
||||||
|
private static final String JMX_SERVER_HOSTNAME = "localhost";
|
||||||
|
private static final int JMX_SERVER_PORT = 10099;
|
||||||
|
|
||||||
|
public static final String SERVER_NAME = "audit-logging";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws Exception {
|
||||||
|
cleanupData(SERVER_NAME);
|
||||||
|
disableCheckThread();
|
||||||
|
startServer(SERVER_NAME, 0, 30000);
|
||||||
|
emptyLogFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void emptyLogFile() throws Exception {
|
||||||
|
if (auditLog.exists()) {
|
||||||
|
try (PrintWriter writer = new PrintWriter(new FileWriter(auditLog))) {
|
||||||
|
writer.print("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditResourceLog() throws Exception {
|
||||||
|
HashMap environment = new HashMap();
|
||||||
|
String[] credentials = new String[] {"admin", "admin"};
|
||||||
|
environment.put(JMXConnector.CREDENTIALS, credentials);
|
||||||
|
// Without this, the RMI server would bind to the default interface IP (the user's local IP mostly)
|
||||||
|
System.setProperty("java.rmi.server.hostname", JMX_SERVER_HOSTNAME);
|
||||||
|
|
||||||
|
// I don't specify both ports here manually on purpose. See actual RMI registry connection port extraction below.
|
||||||
|
String urlString = "service:jmx:rmi:///jndi/rmi://" + JMX_SERVER_HOSTNAME + ":" + JMX_SERVER_PORT + "/jmxrmi";
|
||||||
|
|
||||||
|
JMXServiceURL url = new JMXServiceURL(urlString);
|
||||||
|
JMXConnector jmxConnector = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
jmxConnector = JMXConnectorFactory.connect(url, environment);
|
||||||
|
System.out.println("Successfully connected to: " + urlString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
jmxConnector = null;
|
||||||
|
e.printStackTrace();
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
|
||||||
|
String brokerName = "0.0.0.0"; // configured e.g. in broker.xml <broker-name> element
|
||||||
|
ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), brokerName, true);
|
||||||
|
ActiveMQServerControl serverControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getActiveMQServerObjectName(), ActiveMQServerControl.class, false);
|
||||||
|
|
||||||
|
serverControl.createAddress("auditAddress", "ANYCAST,MULTICAST");
|
||||||
|
checkAuditLogRecord(true, "successfully created Address:");
|
||||||
|
serverControl.updateAddress("auditAddress", "ANYCAST");
|
||||||
|
checkAuditLogRecord(true, "successfully updated Address:");
|
||||||
|
serverControl.deleteAddress("auditAddress");
|
||||||
|
checkAuditLogRecord(true, "successfully deleted Address:");
|
||||||
|
serverControl.createQueue("auditAddress", "auditQueue", "ANYCAST");
|
||||||
|
checkAuditLogRecord(true, "successfully created Queue:");
|
||||||
|
serverControl.updateQueue("auditQueue", "ANYCAST", -1, false);
|
||||||
|
final QueueControl queueControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection,
|
||||||
|
objectNameBuilder.getQueueObjectName(new SimpleString( "auditAddress"), new SimpleString("auditQueue"), RoutingType.ANYCAST),
|
||||||
|
QueueControl.class,
|
||||||
|
false);
|
||||||
|
checkAuditLogRecord(true, "successfully updated Queue:");
|
||||||
|
queueControl.removeAllMessages();
|
||||||
|
checkAuditLogRecord(true, "has removed 0 messages");
|
||||||
|
queueControl.sendMessage(new HashMap<>(), 0, "foo", true, "admin", "admin");
|
||||||
|
checkAuditLogRecord(true, "sent message to");
|
||||||
|
CompositeData[] browse = queueControl.browse();
|
||||||
|
checkAuditLogRecord(true, "browsed " + browse.length + " messages");
|
||||||
|
serverControl.destroyQueue("auditQueue");
|
||||||
|
checkAuditLogRecord(true, "successfully deleted Queue:");
|
||||||
|
|
||||||
|
ServerLocator locator = createNettyNonHALocator();
|
||||||
|
ClientSessionFactory sessionFactory = locator.createSessionFactory();
|
||||||
|
ClientSession session = sessionFactory.createSession("admin", "admin", false, false, true, false, 0);
|
||||||
|
ClientProducer producer = session.createProducer("myQ");
|
||||||
|
producer.send(session.createMessage(true));
|
||||||
|
locator.close();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
jmxConnector.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check the audit log has a line that contains all the values
|
||||||
|
private void checkAuditLogRecord(boolean exist, String... values) throws Exception {
|
||||||
|
Assert.assertTrue(auditLog.exists());
|
||||||
|
boolean hasRecord = false;
|
||||||
|
try (BufferedReader reader = new BufferedReader(new FileReader(auditLog))) {
|
||||||
|
String line = reader.readLine();
|
||||||
|
while (line != null) {
|
||||||
|
if (line.contains(values[0])) {
|
||||||
|
boolean hasAll = true;
|
||||||
|
for (int i = 1; i < values.length; i++) {
|
||||||
|
if (!line.contains(values[i])) {
|
||||||
|
hasAll = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasAll) {
|
||||||
|
hasRecord = true;
|
||||||
|
System.out.println("audit has it: " + line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = reader.readLine();
|
||||||
|
}
|
||||||
|
if (exist) {
|
||||||
|
Assert.assertTrue(hasRecord);
|
||||||
|
} else {
|
||||||
|
Assert.assertFalse(hasRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,114 +14,69 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.artemis.tests.integration.management;
|
package org.apache.activemq.artemis.tests.smoke.logging;
|
||||||
|
|
||||||
|
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||||
import org.apache.activemq.artemis.api.core.Message;
|
import org.apache.activemq.artemis.api.core.Message;
|
||||||
import org.apache.activemq.artemis.api.core.QueueConfiguration;
|
import org.apache.activemq.artemis.api.core.QueueConfiguration;
|
||||||
import org.apache.activemq.artemis.api.core.RoutingType;
|
import org.apache.activemq.artemis.api.core.RoutingType;
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||||
import org.apache.activemq.artemis.api.core.TransportConfiguration;
|
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
|
||||||
|
import org.apache.activemq.artemis.api.core.client.ClientMessage;
|
||||||
|
import org.apache.activemq.artemis.api.core.client.ClientProducer;
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientSession;
|
import org.apache.activemq.artemis.api.core.client.ClientSession;
|
||||||
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
|
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
|
||||||
import org.apache.activemq.artemis.api.core.client.ServerLocator;
|
import org.apache.activemq.artemis.api.core.client.ServerLocator;
|
||||||
import org.apache.activemq.artemis.api.core.management.AddressControl;
|
import org.apache.activemq.artemis.api.core.management.AddressControl;
|
||||||
import org.apache.activemq.artemis.core.config.Configuration;
|
import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
|
||||||
import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
|
import org.apache.activemq.artemis.tests.smoke.common.SmokeTestBase;
|
||||||
import org.apache.activemq.artemis.core.security.Role;
|
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServers;
|
|
||||||
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
|
|
||||||
import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
|
|
||||||
import org.apache.activemq.artemis.tests.util.Wait;
|
|
||||||
import org.apache.activemq.artemis.utils.Base64;
|
import org.apache.activemq.artemis.utils.Base64;
|
||||||
import org.apache.activemq.artemis.utils.RandomUtil;
|
import org.apache.activemq.artemis.utils.RandomUtil;
|
||||||
import org.junit.After;
|
import org.apache.activemq.artemis.utils.Wait;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.management.MBeanServerConnection;
|
||||||
|
import javax.management.MBeanServerInvocationHandler;
|
||||||
|
import javax.management.remote.JMXConnector;
|
||||||
|
import javax.management.remote.JMXConnectorFactory;
|
||||||
|
import javax.management.remote.JMXServiceURL;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.URI;
|
import java.net.MalformedURLException;
|
||||||
import java.util.HashSet;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.LogManager;
|
|
||||||
|
|
||||||
// https://issues.apache.org/jira/browse/ARTEMIS-2730 this test needs to be moved as a SmokeTest
|
public class AuditLoggerTest extends SmokeTestBase {
|
||||||
// as it's messing up with logging configurations
|
|
||||||
@Ignore
|
|
||||||
public class AuditLoggerTest extends ManagementTestBase {
|
|
||||||
|
|
||||||
private static final File auditLog = new File("target/audit.log");
|
private static final File auditLog = new File("target/audit-logging2/log/audit.log");
|
||||||
|
|
||||||
|
private static final String JMX_SERVER_HOSTNAME = "localhost";
|
||||||
|
private static final int JMX_SERVER_PORT = 10099;
|
||||||
|
|
||||||
|
public static final String SERVER_NAME = "audit-logging2";
|
||||||
|
|
||||||
private ActiveMQServer server;
|
|
||||||
private Configuration conf;
|
|
||||||
protected ClientSession session;
|
protected ClientSession session;
|
||||||
private ServerLocator locator;
|
private ServerLocator locator;
|
||||||
private ClientSessionFactory sf;
|
private ClientSessionFactory sf;
|
||||||
|
|
||||||
@Override
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void before() throws Exception {
|
||||||
super.setUp();
|
cleanupData(SERVER_NAME);
|
||||||
|
disableCheckThread();
|
||||||
|
startServer(SERVER_NAME, 0, 30000);
|
||||||
emptyLogFile();
|
emptyLogFile();
|
||||||
|
locator = createNonHALocator(true).setBlockOnNonDurableSend(true);
|
||||||
TransportConfiguration connectorConfig = new TransportConfiguration(INVM_CONNECTOR_FACTORY);
|
|
||||||
|
|
||||||
conf = createDefaultNettyConfig().setJMXManagementEnabled(true).addConnectorConfiguration(connectorConfig.getName(), connectorConfig);
|
|
||||||
conf.setSecurityEnabled(true);
|
|
||||||
SecurityConfiguration securityConfiguration = new SecurityConfiguration();
|
|
||||||
securityConfiguration.addUser("guest", "guest");
|
|
||||||
securityConfiguration.addUser("myUser", "myPass");
|
|
||||||
securityConfiguration.addRole("guest", "guest");
|
|
||||||
securityConfiguration.addRole("myUser", "guest");
|
|
||||||
securityConfiguration.setDefaultUser("guest");
|
|
||||||
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager(InVMLoginModule.class.getName(), securityConfiguration);
|
|
||||||
server = addServer(ActiveMQServers.newActiveMQServer(conf, mbeanServer, securityManager, true));
|
|
||||||
server.start();
|
|
||||||
|
|
||||||
HashSet<Role> role = new HashSet<>();
|
|
||||||
//role guest cannot delete queues
|
|
||||||
role.add(new Role("guest", true, true, true, false, true, false, true, true, true, true));
|
|
||||||
server.getSecurityRepository().addMatch("#", role);
|
|
||||||
|
|
||||||
locator = createInVMNonHALocator().setBlockOnNonDurableSend(true);
|
|
||||||
sf = createSessionFactory(locator);
|
sf = createSessionFactory(locator);
|
||||||
session = sf.createSession("guest", "guest", false, true, false, false, 100);
|
session = sf.createSession("guest", "guest", false, true, false, false, 100);
|
||||||
session.start();
|
session.start();
|
||||||
addClientSession(session);
|
addClientSession(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
super.tearDown();
|
|
||||||
|
|
||||||
String originalLoggingConfig = System.getProperty("logging.configuration");
|
|
||||||
|
|
||||||
if (originalLoggingConfig != null) {
|
|
||||||
File file = new File(new URI(originalLoggingConfig));
|
|
||||||
InputStream inputStream = new FileInputStream(file);
|
|
||||||
|
|
||||||
LogManager logManager = LogManager.getLogManager();
|
|
||||||
try {
|
|
||||||
logManager.readConfiguration(inputStream);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("error loading logging conifg");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void emptyLogFile() throws Exception {
|
private void emptyLogFile() throws Exception {
|
||||||
if (auditLog.exists()) {
|
if (auditLog.exists()) {
|
||||||
try (PrintWriter writer = new PrintWriter(new FileWriter(auditLog))) {
|
try (PrintWriter writer = new PrintWriter(new FileWriter(auditLog))) {
|
||||||
|
@ -132,11 +87,15 @@ public class AuditLoggerTest extends ManagementTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuditLog() throws Exception {
|
public void testAuditLog() throws Exception {
|
||||||
reloadLoggingConfig("audit.logging.properties");
|
JMXConnector jmxConnector = getJmxConnector();
|
||||||
|
|
||||||
|
MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
|
||||||
|
String brokerName = "0.0.0.0"; // configured e.g. in broker.xml <broker-name> element
|
||||||
|
ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), brokerName, true);
|
||||||
SimpleString address = RandomUtil.randomSimpleString();
|
SimpleString address = RandomUtil.randomSimpleString();
|
||||||
session.createAddress(address, RoutingType.ANYCAST, false);
|
session.createAddress(address, RoutingType.ANYCAST, false);
|
||||||
|
|
||||||
final AddressControl addressControl = ManagementControlHelper.createAddressControl(address, mbeanServer);
|
final AddressControl addressControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getAddressObjectName(address), AddressControl.class, false);
|
||||||
|
|
||||||
Assert.assertEquals(0, addressControl.getQueueNames().length);
|
Assert.assertEquals(0, addressControl.getQueueNames().length);
|
||||||
session.createQueue(new QueueConfiguration(address).setRoutingType(RoutingType.ANYCAST));
|
session.createQueue(new QueueConfiguration(address).setRoutingType(RoutingType.ANYCAST));
|
||||||
|
@ -153,62 +112,90 @@ public class AuditLoggerTest extends ManagementTestBase {
|
||||||
address = RandomUtil.randomSimpleString();
|
address = RandomUtil.randomSimpleString();
|
||||||
session.createAddress(address, RoutingType.ANYCAST, false);
|
session.createAddress(address, RoutingType.ANYCAST, false);
|
||||||
|
|
||||||
final AddressControl addressControl2 = ManagementControlHelper.createAddressControl(address, mbeanServer);
|
final AddressControl addressControl2 = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getAddressObjectName(address), AddressControl.class, false);
|
||||||
|
|
||||||
Assert.assertEquals(1, addressControl.getQueueNames().length);
|
Assert.assertEquals(1, addressControl.getQueueNames().length);
|
||||||
|
|
||||||
session.createQueue(new QueueConfiguration(address).setRoutingType(RoutingType.ANYCAST).setDurable(false));
|
session.createQueue(new QueueConfiguration(address).setRoutingType(RoutingType.ANYCAST).setDurable(false));
|
||||||
Wait.waitFor(() -> addressControl2.getQueueNames().length == 1);
|
Wait.waitFor(() -> addressControl2.getQueueNames().length == 1);
|
||||||
|
|
||||||
|
ClientProducer producer = session.createProducer(address);
|
||||||
|
producer.send(session.createMessage(true));
|
||||||
|
Wait.waitFor(() -> addressControl.getMessageCount() == 1);
|
||||||
try {
|
try {
|
||||||
session.deleteQueue(address);
|
session.deleteQueue(address);
|
||||||
fail("Deleting queue should get exception");
|
Assert.fail("Deleting queue should get exception");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAuditLogRecord(true, "gets security check failure:", "guest does not have permission='DELETE_NON_DURABLE_QUEUE'");
|
checkAuditLogRecord(true, "gets security check failure:", "guest does not have permission='DELETE_NON_DURABLE_QUEUE'");
|
||||||
//hot patch not in log
|
//hot patch not in log
|
||||||
checkAuditLogRecord(false, "is sending a core message");
|
checkAuditLogRecord(true, "is sending a core message");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadLoggingConfig(String logFile) {
|
protected JMXConnector getJmxConnector() throws MalformedURLException {
|
||||||
ClassLoader cl = AuditLoggerTest.class.getClassLoader();
|
HashMap environment = new HashMap();
|
||||||
InputStream inputStream = cl.getResourceAsStream(logFile);
|
String[] credentials = new String[] {"admin", "admin"};
|
||||||
LogManager logManager = LogManager.getLogManager();
|
environment.put(JMXConnector.CREDENTIALS, credentials);
|
||||||
|
// Without this, the RMI server would bind to the default interface IP (the user's local IP mostly)
|
||||||
|
System.setProperty("java.rmi.server.hostname", JMX_SERVER_HOSTNAME);
|
||||||
|
|
||||||
|
// I don't specify both ports here manually on purpose. See actual RMI registry connection port extraction below.
|
||||||
|
String urlString = "service:jmx:rmi:///jndi/rmi://" + JMX_SERVER_HOSTNAME + ":" + JMX_SERVER_PORT + "/jmxrmi";
|
||||||
|
|
||||||
|
JMXServiceURL url = new JMXServiceURL(urlString);
|
||||||
|
JMXConnector jmxConnector = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logManager.readConfiguration(inputStream);
|
jmxConnector = JMXConnectorFactory.connect(url, environment);
|
||||||
inputStream.close();
|
System.out.println("Successfully connected to: " + urlString);
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
System.out.println("error loading logging conifg");
|
jmxConnector = null;
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
Assert.fail(e.getMessage());
|
||||||
}
|
}
|
||||||
|
return jmxConnector;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuditHotLog() throws Exception {
|
public void testAuditHotLog() throws Exception {
|
||||||
reloadLoggingConfig("audit.logging.hot.properties");
|
JMXConnector jmxConnector = getJmxConnector();
|
||||||
|
MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
|
||||||
|
String brokerName = "0.0.0.0"; // configured e.g. in broker.xml <broker-name> element
|
||||||
|
ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), brokerName, true);
|
||||||
SimpleString address = RandomUtil.randomSimpleString();
|
SimpleString address = RandomUtil.randomSimpleString();
|
||||||
session.createAddress(address, RoutingType.ANYCAST, false);
|
session.createAddress(address, RoutingType.ANYCAST, false);
|
||||||
|
|
||||||
final AddressControl addressControl = ManagementControlHelper.createAddressControl(address, mbeanServer);
|
final AddressControl addressControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getAddressObjectName(address), AddressControl.class, false);
|
||||||
|
|
||||||
Assert.assertEquals(0, addressControl.getQueueNames().length);
|
Assert.assertEquals(0, addressControl.getQueueNames().length);
|
||||||
session.createQueue(new QueueConfiguration(address).setRoutingType(RoutingType.ANYCAST));
|
session.createQueue(new QueueConfiguration(address).setRoutingType(RoutingType.ANYCAST));
|
||||||
Assert.assertEquals(1, addressControl.getQueueNames().length);
|
Assert.assertEquals(1, addressControl.getQueueNames().length);
|
||||||
String uniqueStr = Base64.encodeBytes(UUID.randomUUID().toString().getBytes());
|
String uniqueStr = Base64.encodeBytes(UUID.randomUUID().toString().getBytes());
|
||||||
addressControl.sendMessage(null, Message.BYTES_TYPE, uniqueStr, false, null, null);
|
|
||||||
|
|
||||||
Wait.waitFor(() -> addressControl.getMessageCount() == 1);
|
ClientProducer producer = session.createProducer(address);
|
||||||
Assert.assertEquals(1, addressControl.getMessageCount());
|
producer.send(session.createMessage(true));
|
||||||
|
producer.send(session.createMessage(true));
|
||||||
|
// addressControl.sendMessage(null, Message.BYTES_TYPE, uniqueStr, false, null, null);
|
||||||
|
|
||||||
|
Wait.waitFor(() -> addressControl.getMessageCount() == 2);
|
||||||
|
Assert.assertEquals(2, addressControl.getMessageCount());
|
||||||
|
|
||||||
checkAuditLogRecord(true, "sending a core message");
|
checkAuditLogRecord(true, "sending a core message");
|
||||||
|
|
||||||
|
ClientConsumer consumer = session.createConsumer(address);
|
||||||
|
session.start();
|
||||||
|
ClientMessage clientMessage = consumer.receiveImmediate();
|
||||||
|
Assert.assertNotNull(clientMessage);
|
||||||
|
clientMessage = consumer.receiveImmediate();
|
||||||
|
Assert.assertNotNull(clientMessage);
|
||||||
|
checkAuditLogRecord(true, "is consuming a message from");
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the audit log has a line that contains all the values
|
//check the audit log has a line that contains all the values
|
||||||
private void checkAuditLogRecord(boolean exist, String... values) throws Exception {
|
private void checkAuditLogRecord(boolean exist, String... values) throws Exception {
|
||||||
assertTrue(auditLog.exists());
|
Assert.assertTrue(auditLog.exists());
|
||||||
boolean hasRecord = false;
|
boolean hasRecord = false;
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(auditLog))) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(auditLog))) {
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
|
@ -230,9 +217,9 @@ public class AuditLoggerTest extends ManagementTestBase {
|
||||||
line = reader.readLine();
|
line = reader.readLine();
|
||||||
}
|
}
|
||||||
if (exist) {
|
if (exist) {
|
||||||
assertTrue(hasRecord);
|
Assert.assertTrue(hasRecord);
|
||||||
} else {
|
} else {
|
||||||
assertFalse(hasRecord);
|
Assert.assertFalse(hasRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue