This is an automated email from the ASF dual-hosted git repository.

cshannon pushed a commit to branch activemq-5.15.x
in repository https://gitbox.apache.org/repos/asf/activemq.git

commit 70b2a4318375a573bdbda61303f5cfc19d33ff7d
Author: gtully <[email protected]>
AuthorDate: Thu Nov 8 12:10:01 2018 +0000

    AMQ-7094 - track the objectName with an annotated mbean such that the jmx 
audit log event can extract that target of an mbean operation, fix and test
    
    (cherry picked from commit d2b0affedb38c5439bce2fb5a8e321bc5d0ec713)
---
 .../apache/activemq/broker/jmx/AnnotatedMBean.java | 26 +++++++-
 .../activemq/broker/jmx/AsyncAnnotatedMBean.java   | 12 ++--
 .../activemq/broker/util/JMXAuditLogEntry.java     | 13 +++-
 .../java/org/apache/activemq/jmx/DLQRetryTest.java |  1 +
 .../org/apache/activemq/jmx/JmxAuditLogTest.java   | 75 ++++++++++++++++++++++
 .../org/apache/activemq/jmx/JmxCreateNCTest.java   |  3 +
 6 files changed, 120 insertions(+), 10 deletions(-)

diff --git 
a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
index c75d8a8..dc772c2 100644
--- 
a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
+++ 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
@@ -68,6 +68,8 @@ public class AnnotatedMBean extends StandardMBean {
         }
     }
 
+    private final ObjectName objectName;
+
     private static byte byteFromProperty(String s) {
         byte val = OFF;
         String config = System.getProperty(s, "").toLowerCase(Locale.ENGLISH);
@@ -88,7 +90,7 @@ public class AnnotatedMBean extends StandardMBean {
 
         for (Class c : object.getClass().getInterfaces()) {
             if (mbeanName.equals(c.getName())) {
-                context.registerMBean(new AnnotatedMBean(object, c), 
objectName);
+                context.registerMBean(new AnnotatedMBean(object, c, 
objectName), objectName);
                 return;
             }
         }
@@ -97,13 +99,15 @@ public class AnnotatedMBean extends StandardMBean {
     }
 
     /** Instance where the MBean interface is implemented by another object. */
-    public <T> AnnotatedMBean(T impl, Class<T> mbeanInterface) throws 
NotCompliantMBeanException {
+    public <T> AnnotatedMBean(T impl, Class<T> mbeanInterface, ObjectName 
objectName) throws NotCompliantMBeanException {
         super(impl, mbeanInterface);
+        this.objectName = objectName;
     }
 
     /** Instance where the MBean interface is implemented by this object. */
-    protected AnnotatedMBean(Class<?> mbeanInterface) throws 
NotCompliantMBeanException {
+    protected AnnotatedMBean(Class<?> mbeanInterface, ObjectName objectName) 
throws NotCompliantMBeanException {
         super(mbeanInterface);
+        this.objectName = objectName;
     }
 
     /** {@inheritDoc} */
@@ -212,6 +216,7 @@ public class AnnotatedMBean extends StandardMBean {
             entry = new JMXAuditLogEntry();
             entry.setUser(caller);
             entry.setTimestamp(System.currentTimeMillis());
+            entry.setTarget(extractTargetTypeProperty(objectName));
             entry.setOperation(this.getMBeanInfo().getClassName() + "." + s);
 
             try
@@ -245,6 +250,21 @@ public class AnnotatedMBean extends StandardMBean {
         return result;
     }
 
+    // keep brokerName last b/c objectNames include the brokerName
+    final static String[] targetPropertiesCandidates = new String[] 
{"destinationName", "networkConnectorName", "connectorName", "connectionName", 
"brokerName"};
+    private String extractTargetTypeProperty(ObjectName objectName) {
+        String result = null;
+        for (String attr: targetPropertiesCandidates) {
+            try {
+                result = objectName.getKeyProperty(attr);
+                if (result != null) {
+                    break;
+                }
+            } catch (NullPointerException ok) {}
+        }
+        return result;
+    }
+
     private Method getMBeanMethod(Class clazz, String methodName, String[] 
signature) throws ReflectiveOperationException {
         Class[] parameterTypes = new Class[signature.length];
         for (int i = 0; i < signature.length; i++) {
diff --git 
a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AsyncAnnotatedMBean.java
 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AsyncAnnotatedMBean.java
index 7460e16..7871a21 100644
--- 
a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AsyncAnnotatedMBean.java
+++ 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AsyncAnnotatedMBean.java
@@ -36,15 +36,15 @@ public class AsyncAnnotatedMBean extends AnnotatedMBean {
     private ExecutorService executor;
     private long timeout = 0;
 
-    public <T> AsyncAnnotatedMBean(ExecutorService executor, long timeout, T 
impl, Class<T> mbeanInterface) throws NotCompliantMBeanException {
-        super(impl, mbeanInterface);
+    public <T> AsyncAnnotatedMBean(ExecutorService executor, long timeout, T 
impl, Class<T> mbeanInterface, ObjectName objectName) throws 
NotCompliantMBeanException {
+        super(impl, mbeanInterface, objectName);
 
         this.executor = executor;
         this.timeout = timeout;
     }
 
-    protected AsyncAnnotatedMBean(Class<?> mbeanInterface) throws 
NotCompliantMBeanException {
-        super(mbeanInterface);
+    protected AsyncAnnotatedMBean(Class<?> mbeanInterface, ObjectName 
objectName) throws NotCompliantMBeanException {
+        super(mbeanInterface, objectName);
     }
 
     protected Object asyncInvole(String s, Object[] objects, String[] strings) 
throws MBeanException, ReflectionException {
@@ -67,9 +67,9 @@ public class AsyncAnnotatedMBean extends AnnotatedMBean {
         for (Class c : object.getClass().getInterfaces()) {
             if (mbeanName.equals(c.getName())) {
                 if (timeout == 0) {
-                    context.registerMBean(new AnnotatedMBean(object, c), 
objectName);
+                    context.registerMBean(new AnnotatedMBean(object, c, 
objectName), objectName);
                 } else {
-                    context.registerMBean(new AsyncAnnotatedMBean(executor, 
timeout, object, c), objectName);
+                    context.registerMBean(new AsyncAnnotatedMBean(executor, 
timeout, object, c, objectName), objectName);
                 }
                 return;
             }
diff --git 
a/activemq-broker/src/main/java/org/apache/activemq/broker/util/JMXAuditLogEntry.java
 
b/activemq-broker/src/main/java/org/apache/activemq/broker/util/JMXAuditLogEntry.java
index 7e0e0e3..3ced281 100644
--- 
a/activemq-broker/src/main/java/org/apache/activemq/broker/util/JMXAuditLogEntry.java
+++ 
b/activemq-broker/src/main/java/org/apache/activemq/broker/util/JMXAuditLogEntry.java
@@ -21,14 +21,25 @@ import java.util.Arrays;
 public class JMXAuditLogEntry extends AuditLogEntry {
     public static final String[] VERBS = new String[] {" called ", " ended "};
     private int state = 0;
+    protected String target;
 
     public void complete() {
         setTimestamp(System.currentTimeMillis());
         state = 1;
     }
 
+    public String getTarget() {
+        return target;
+    }
+
+    public void setTarget(String target) {
+        this.target = target;
+    }
+
     @Override
     public String toString() {
-        return user.trim() + VERBS[state] + operation + 
Arrays.toString((Object[])parameters.get("arguments")) + " at " + 
getFormattedTime();
+        return user.trim() + VERBS[state] + operation + 
Arrays.toString((Object[])parameters.get("arguments"))
+                + (target != null ? " on " + target : "")
+                + " at " + getFormattedTime();
     }
 }
diff --git 
a/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/DLQRetryTest.java 
b/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/DLQRetryTest.java
index e2875fb..e4f3c16 100644
--- 
a/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/DLQRetryTest.java
+++ 
b/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/DLQRetryTest.java
@@ -151,6 +151,7 @@ public class DLQRetryTest extends EmbeddedBrokerTestSupport 
{
     }
 
     protected void setUp() throws Exception {
+        System.setProperty("org.apache.activemq.audit", "all");
         bindAddress = "tcp://localhost:0";
         useTopic = false;
         super.setUp();
diff --git 
a/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxAuditLogTest.java
 
b/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxAuditLogTest.java
index e6f1083..5256b96 100644
--- 
a/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxAuditLogTest.java
+++ 
b/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxAuditLogTest.java
@@ -30,6 +30,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.activemq.TestSupport;
 import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.TransportConnector;
+import org.apache.activemq.broker.jmx.BrokerMBeanSupport;
 import org.apache.activemq.broker.jmx.ManagementContext;
 import org.apache.activemq.command.ActiveMQDestination;
 import org.apache.activemq.command.ActiveMQQueue;
@@ -62,10 +64,13 @@ public class JmxAuditLogTest extends TestSupport
 
       broker = new BrokerService();
       broker.setUseJmx(true);
+      broker.setDeleteAllMessagesOnStartup(true);
       portToUse = findOpenPort();
       broker.setManagementContext(createManagementContext("broker", 
portToUse));
       broker.setPopulateUserNameInMBeans(true);
       broker.setDestinations(createDestinations());
+      TransportConnector transportConnector = 
broker.addConnector("tcp://0.0.0.0:0");
+      transportConnector.setName("TCP");
       broker.start();
    }
 
@@ -154,4 +159,74 @@ public class JmxAuditLogTest extends TestSupport
       assertEquals("got two messages", 2, logCount.get());
 
    }
+
+   @Test
+   public void testNameTargetVisible() throws Exception
+   {
+      Logger log4jLogger = Logger.getLogger("org.apache.activemq.audit");
+      log4jLogger.setLevel(Level.INFO);
+      final AtomicInteger logCount = new AtomicInteger(0);
+      final AtomicBoolean gotEnded = new AtomicBoolean(false);
+      final AtomicBoolean gotQueueName = new AtomicBoolean(false);
+      final AtomicBoolean gotBrokerName = new AtomicBoolean(false);
+      final AtomicBoolean gotConnectorName = new AtomicBoolean(false);
+
+      final String queueName = queue.getQueueName();
+      Appender appender = new DefaultTestAppender()
+      {
+         @Override
+         public void doAppend(LoggingEvent event)
+         {
+            if (event.getMessage() instanceof String)
+            {
+               String message = (String) event.getMessage();
+               System.out.println(message);
+               if (message.contains(VERBS[0])) {
+                  if (message.contains(queueName)) {
+                     gotQueueName.set(true);
+                  }
+                  if (message.contains(broker.getBrokerName())) {
+                     gotBrokerName.set(true);
+                  }
+
+                  if (message.contains("TCP")) {
+                     gotConnectorName.set(true);
+                  }
+               }
+
+               if (message.contains(VERBS[1])) {
+                  gotEnded.set(true);
+               }
+            }
+            logCount.incrementAndGet();
+         }
+      };
+      log4jLogger.addAppender(appender);
+
+      MBeanServerConnection conn = createJMXConnector(portToUse);
+      ObjectName queueObjName = new ObjectName(broker.getBrokerObjectName() + 
",destinationType=Queue,destinationName=" + queueName);
+
+      Object[] params = {};
+      String[] signature = {};
+
+      conn.invoke(queueObjName, "purge", params, signature);
+
+      assertTrue("got ended statement", gotEnded.get());
+      assertEquals("got two messages", 2, logCount.get());
+      assertTrue("got queueName in called statement", gotQueueName.get());
+
+      // call broker to verify brokerName
+      conn.invoke(broker.getBrokerObjectName(), "resetStatistics", params, 
signature);
+      assertEquals("got 4 messages", 4, logCount.get());
+      assertTrue("got brokerName in called statement", gotBrokerName.get());
+
+
+      ObjectName transportConnectorON = 
BrokerMBeanSupport.createConnectorName(broker.getBrokerObjectName(), 
"clientConnectors", "TCP");
+      conn.invoke(transportConnectorON, "stop", params, signature);
+      assertEquals("got messages", 6, logCount.get());
+      assertTrue("got connectorName in called statement", 
gotConnectorName.get());
+
+      log4jLogger.removeAppender(appender);
+
+   }
 }
diff --git 
a/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxCreateNCTest.java
 
b/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxCreateNCTest.java
index e96c596..1d878b4 100644
--- 
a/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxCreateNCTest.java
+++ 
b/activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxCreateNCTest.java
@@ -38,6 +38,9 @@ public class JmxCreateNCTest {
 
     @Test
     public void testBridgeRegistration() throws Exception {
+
+        System.setProperty("org.apache.activemq.audit", "all");
+
         BrokerService broker = new BrokerService();
         broker.setBrokerName(BROKER_NAME);
         broker.setUseJmx(true); // explicitly set this so no funny issues

Reply via email to