/* * #%L * Nazgul Project: nazgul-core-jmx-api * %% * Copyright (C) 2010 - 2017 jGuru Europe AB * %% * Licensed under the jGuru Europe AB license (the "License"), based * on Apache License, Version 2.0; you may not use this file except * in compliance with the License. * * You may obtain a copy of the License at * * http://www.jguru.se/licenses/jguruCorporateSourceLicense-2.0.txt * * 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. * #L% * */ package se.jguru.nazgul.core.jmx.api; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.slf4j.LoggerFactory; import se.jguru.nazgul.core.jmx.api.event.DefaultNotificationEmitter; import se.jguru.nazgul.core.jmx.api.helper.TestAbstractMBean; import se.jguru.nazgul.core.jmx.api.helper.TestNotificationListener; import se.jguru.nazgul.core.jmx.test.mbeanserver.AbstractJmxTest; import javax.management.MBeanServer; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.RuntimeMBeanException; import java.util.Arrays; import java.util.List; /** * @author <a href="mailto:lj@jguru.se">Lennart Jörelid, jGuru Europe AB</a> */ public class T_AbstractJmxTest extends AbstractJmxTest { // Shared state private ObjectName mbeanName; private TestAbstractMBean unitUnderTest; private DefaultNotificationEmitter emitter; private TestNotificationListener listener; private ListAppender<ILoggingEvent> debugAppender; /** * {@inheritDoc} */ @Before public void customSetupSharedState() throws Exception { // Add a debug Logging adapter. // assume SLF4J is bound to logback in the current environment LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); final Logger abstractMbeanLogger = context.getLogger(AbstractMBean.class); Assert.assertNotNull("Null abstractMBeanLogger", abstractMbeanLogger); // Add and start a new Appender to collect all log statements. debugAppender = new ListAppender<ILoggingEvent>(); abstractMbeanLogger.addAppender(debugAppender); debugAppender.start(); // Create the unitUnderTest and register it using the test names. mbeanName = new ObjectName(getTestDomain(), "type", TestAbstractMBean.class.getSimpleName()); emitter = DefaultNotificationEmitter.getDefaultStateChangeNotificationEmitter("testId"); unitUnderTest = new TestAbstractMBean(LifecycleStateful.class, emitter); // Add a notification listener to receive notifications from the TestAbstractMBean. listener = new TestNotificationListener(); unitUnderTest.addNotificationListener(listener, null, "handback!"); } @Test public void validateLifecycleStateTransitions() throws Exception { // Assemble final MBeanServer mBeanServer = rule.getMBeanServer(); final List<LifecycleState> expected = Arrays.asList( LifecycleState.STARTING, LifecycleState.STARTED, LifecycleState.STOPPING, LifecycleState.STOPPED); // Act final ObjectInstance mBean = mBeanServer.registerMBean(unitUnderTest, mbeanName); final LifecycleState state = LifecycleState.valueOf("" + getAttribute(mBean.getObjectName(), "State")); mBeanServer.unregisterMBean(mbeanName); // Assert for (int i = 0; i < expected.size(); i++) { Assert.assertEquals(expected.get(i), listener.states.get(i)); } Assert.assertEquals(LifecycleState.STARTED, state); Assert.assertTrue(unitUnderTest.preRegisterInvoked); Assert.assertTrue(unitUnderTest.postRegisterInvoked); Assert.assertTrue(unitUnderTest.preDeregisterInvoked); Assert.assertTrue(unitUnderTest.postDeregisterInvoked); } @Test public void validateExceptionWrappingOnPreRegistrationException() throws Exception { // Assemble final MBeanServer mBeanServer = rule.getMBeanServer(); unitUnderTest.throwPreRegisterException = true; // Act & Assert try { mBeanServer.registerMBean(unitUnderTest, mbeanName); Assert.fail("Exceptions thrown during preRegistration should not be caught and handled by AbstractMBean."); } catch (RuntimeMBeanException e) { // Expected Assert.assertTrue("The inner exception, thrown by the AbstractMBean should be preserved as cause.", e.getCause() instanceof IllegalArgumentException); } catch (Exception e) { Assert.fail("Expected RuntimeMBeanException, but got [" + e.getClass().getName() + "]"); } Assert.assertTrue(unitUnderTest.preRegisterInvoked); Assert.assertFalse(unitUnderTest.postRegisterInvoked); Assert.assertFalse(unitUnderTest.preDeregisterInvoked); Assert.assertFalse(unitUnderTest.postDeregisterInvoked); } @Test public void validateLifecycleStateTransitionsOnExceptionInPostRegister() throws Exception { // Assemble final MBeanServer mBeanServer = rule.getMBeanServer(); final List<LifecycleState> expected = Arrays.asList( LifecycleState.STARTING, LifecycleState.ERROR, LifecycleState.ERROR ); unitUnderTest.throwPostRegisterException = true; // Act final ObjectInstance mBean = mBeanServer.registerMBean(unitUnderTest, mbeanName); final LifecycleState state = LifecycleState.valueOf("" + getAttribute(mBean.getObjectName(), "State")); mBeanServer.unregisterMBean(mbeanName); // Assert Assert.assertEquals(LifecycleState.ERROR, state); for (int i = 0; i < expected.size(); i++) { Assert.assertEquals(expected.get(i), listener.states.get(i)); } Assert.assertTrue(unitUnderTest.preRegisterInvoked); Assert.assertTrue(unitUnderTest.postRegisterInvoked); Assert.assertFalse(unitUnderTest.preDeregisterInvoked); Assert.assertTrue(unitUnderTest.postDeregisterInvoked); } @Test public void validateLifecycleStateTransitionOnExceptionInPreDeregister() throws Exception { // Assemble final MBeanServer mBeanServer = rule.getMBeanServer(); final List<LifecycleState> expected = Arrays.asList( LifecycleState.STARTING, LifecycleState.STARTED, LifecycleState.STOPPING, LifecycleState.ERROR, LifecycleState.ERROR ); unitUnderTest.throwPreDeregisterException = true; // Act final ObjectInstance mBean = mBeanServer.registerMBean(unitUnderTest, mbeanName); final LifecycleState state = LifecycleState.valueOf("" + getAttribute(mBean.getObjectName(), "State")); mBeanServer.unregisterMBean(mbeanName); // Assert Assert.assertEquals(LifecycleState.STARTED, state); for (int i = 0; i < expected.size(); i++) { Assert.assertEquals(expected.get(i), listener.states.get(i)); } Assert.assertTrue(unitUnderTest.preRegisterInvoked); Assert.assertTrue(unitUnderTest.postRegisterInvoked); Assert.assertTrue(unitUnderTest.preDeregisterInvoked); Assert.assertTrue(unitUnderTest.postDeregisterInvoked); } @Test public void validateLifecycleStateTransitionOnExceptionInPostDeregister() throws Exception { // Assemble final MBeanServer mBeanServer = rule.getMBeanServer(); final List<LifecycleState> expected = Arrays.asList( LifecycleState.STARTING, LifecycleState.STARTED, LifecycleState.STOPPING, LifecycleState.ERROR, LifecycleState.ERROR ); unitUnderTest.throwPostDeregisterException = true; // Act final ObjectInstance mBean = mBeanServer.registerMBean(unitUnderTest, mbeanName); final LifecycleState state = LifecycleState.valueOf("" + getAttribute(mBean.getObjectName(), "State")); mBeanServer.unregisterMBean(mbeanName); // Assert Assert.assertEquals(LifecycleState.STARTED, state); for (int i = 0; i < expected.size(); i++) { Assert.assertEquals(expected.get(i), listener.states.get(i)); } Assert.assertTrue(unitUnderTest.preRegisterInvoked); Assert.assertTrue(unitUnderTest.postRegisterInvoked); Assert.assertTrue(unitUnderTest.preDeregisterInvoked); Assert.assertTrue(unitUnderTest.postDeregisterInvoked); } @Test public void validateExceptionOnNullObjectName() throws Exception { // Assemble final MBeanServer mBeanServer = rule.getMBeanServer(); // Act & Assert try { mBeanServer.registerMBean(unitUnderTest, null); Assert.fail("Should not be able to register an AbstractMBean with null objectName."); } catch (RuntimeMBeanException e) { Assert.assertTrue(e.getCause() instanceof IllegalArgumentException); } catch (Exception e) { Assert.fail("Expected RuntimeMBeanException, but got [" + e.getClass().getName() + "]"); } } }