package rocks.inspectit.agent.java.sensor.jmx; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import java.lang.management.ManagementFactory; import java.lang.reflect.Field; import java.util.Collection; import java.util.Collections; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanServer; import javax.management.MBeanServerNotification; import javax.management.Notification; import javax.management.NotificationFilter; import javax.management.NotificationListener; import javax.management.ObjectName; import javax.management.QueryExp; import javax.management.ReflectionException; import javax.management.RuntimeMBeanException; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.slf4j.Logger; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import rocks.inspectit.agent.java.config.IConfigurationStorage; import rocks.inspectit.agent.java.connection.IConnection; import rocks.inspectit.agent.java.core.ICoreService; import rocks.inspectit.agent.java.core.IPlatformManager; import rocks.inspectit.agent.java.sensor.jmx.JmxSensor.MBeanServerHolder; import rocks.inspectit.shared.all.communication.data.JmxSensorValueData; import rocks.inspectit.shared.all.instrumentation.config.impl.JmxAttributeDescriptor; import rocks.inspectit.shared.all.instrumentation.config.impl.JmxSensorTypeConfig; import rocks.inspectit.shared.all.testbase.TestBase; /** * All JMX sensor tests disabled until we support JXM via the Configuration interface. * * @author Ivan Senic * */ @SuppressWarnings({ "unchecked", "PMD", "all" }) public class JmxSensorTest extends TestBase { @InjectMocks JmxSensor jmxSensor; @Mock JmxSensorTypeConfig sensorTypeConfig; @Mock IConnection connection; @Mock IConfigurationStorage configurationStorage; @Mock IPlatformManager platformManager; @Mock MBeanServer mBeanServer; @Mock ICoreService coreService; @Mock MBeanInfo mBeanInfo; @Mock Logger logger; public static class Init extends JmxSensorTest { @Test public void sensorSet() { JmxSensorTypeConfig sensorTypeConfig1 = mock(JmxSensorTypeConfig.class); jmxSensor.init(sensorTypeConfig1); assertThat(jmxSensor.getSensorTypeConfig(), is(sensorTypeConfig1)); } @Test public void serverCreationForced() throws Exception { when(sensorTypeConfig.getParameters()).thenReturn(Collections.<String, Object> singletonMap("forceMBeanServer", Boolean.TRUE)); jmxSensor.init(sensorTypeConfig); // assert that field in Management factory has been created Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer"); field.setAccessible(true); Object server = field.get(null); assertThat(server, is(notNullValue())); } } public static class MbeanServerAdded extends JmxSensorTest { @BeforeMethod public void init() { jmxSensor.init(sensorTypeConfig); } @Test public void nullServer() { jmxSensor.mbeanServerAdded(null); verifyZeroInteractions(connection); } @Test public void listenerRegistered() throws Exception { ArgumentCaptor<MBeanServerHolder> captor = ArgumentCaptor.forClass(MBeanServerHolder.class); jmxSensor.mbeanServerAdded(mBeanServer); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), captor.capture(), Matchers.<NotificationFilter> any(), eq(null)); assertThat(captor.getValue().mBeanServer, is(mBeanServer)); } @Test public void connectionOff() throws Exception { when(connection.isConnected()).thenReturn(false); jmxSensor.mbeanServerAdded(mBeanServer); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); } @Test public void connectionOnRegister() throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); ArgumentCaptor<Collection> captor = ArgumentCaptor.forClass(Collection.class); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), captor.capture())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); jmxSensor.mbeanServerAdded(mBeanServer); JmxAttributeDescriptor sensorConfig = (JmxAttributeDescriptor) captor.getValue().iterator().next(); assertThat(sensorConfig.getId(), is(equalTo(definitionDataIdentId))); assertThat(sensorConfig.getmBeanObjectName(), is(equalTo(testObjectName))); assertThat(sensorConfig.getAttributeName(), is(equalTo(testAttributeName))); assertThat(sensorConfig.getmBeanAttributeDescription(), is(equalTo(testAttrDescription))); assertThat(sensorConfig.getmBeanAttributeType(), is(equalTo(testAttrType))); assertThat(sensorConfig.ismBeanAttributeIsIs(), is(equalTo(testAttrIsIs))); assertThat(sensorConfig.ismBeanAttributeIsReadable(), is(equalTo(testAttrIsReadable))); assertThat(sensorConfig.ismBeanAttributeIsWritable(), is(equalTo(testAttrIsWriteable))); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); } } public static class MbeanServerRemoved extends JmxSensorTest { @BeforeMethod public void init() { jmxSensor.init(sensorTypeConfig); } @Test public void unknownServer() throws Exception { jmxSensor.mbeanServerRemoved(mBeanServer); verifyZeroInteractions(mBeanServer); } @Test public void listenerUnregistered() throws Exception { ArgumentCaptor<MBeanServerHolder> captor = ArgumentCaptor.forClass(MBeanServerHolder.class); jmxSensor.mbeanServerAdded(mBeanServer); jmxSensor.mbeanServerRemoved(mBeanServer); verify(mBeanServer).removeNotificationListener(Matchers.<ObjectName> any(), captor.capture(), Matchers.<NotificationFilter> any(), eq(null)); assertThat(captor.getValue().mBeanServer, is(mBeanServer)); } } public static class Update extends JmxSensorTest { @BeforeMethod public void init() { jmxSensor.init(sensorTypeConfig); } @Test public void nothingToCollect() { jmxSensor.update(coreService); verifyZeroInteractions(coreService); } /** * Tests the registration of a mBean. * * @throws Exception * any occurring exception */ @Test public void registerAndCollect() throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String value = "value"; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), Matchers.<Collection<JmxAttributeDescriptor>> any())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); when(mBeanServer.getAttribute(objectName, testAttributeName)).thenReturn(value); jmxSensor.mbeanServerAdded(mBeanServer); jmxSensor.update(coreService); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).getAttribute(objectName, testAttributeName); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); ArgumentCaptor<JmxSensorValueData> valueCaptor = ArgumentCaptor.forClass(JmxSensorValueData.class); verify(coreService).addJmxSensorValueData(eq(sensorType), eq(testObjectName), eq(testAttributeName), valueCaptor.capture()); assertThat(valueCaptor.getValue().getPlatformIdent(), is(equalTo(platformIdent))); assertThat(valueCaptor.getValue().getSensorTypeIdent(), is(equalTo(sensorType))); assertThat(valueCaptor.getValue().getJmxSensorDefinitionDataIdentId(), is(equalTo(definitionDataIdentId))); assertThat(valueCaptor.getValue().getValue(), is(equalTo(value))); } /** * Tests the registration of a mBean. * * @throws Exception * any occurring exception */ @Test public void registerMonitorNothing() throws Exception { long sensorType = 13L; long platformIdent = 11L; String value = "value"; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), Matchers.<Collection<JmxAttributeDescriptor>> any())).thenReturn(Collections.<JmxAttributeDescriptor> emptyList()); when(mBeanServer.getAttribute(objectName, testAttributeName)).thenReturn(value); jmxSensor.mbeanServerAdded(mBeanServer); jmxSensor.update(coreService); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); verifyZeroInteractions(coreService); } @Test(dataProvider = "throwableProvider") public void collectDataException(Class<? extends Throwable> throwableClass) throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), Matchers.<Collection<JmxAttributeDescriptor>> any())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); when(mBeanServer.getAttribute(objectName, testAttributeName)).thenThrow(throwableClass); jmxSensor.mbeanServerAdded(mBeanServer); // update twice jmxSensor.update(coreService); jmxSensor.lastDataCollectionTimestamp = 0; jmxSensor.update(coreService); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).getAttribute(objectName, testAttributeName); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); } @Test public void collectDataNullValue() throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), Matchers.<Collection<JmxAttributeDescriptor>> any())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); when(mBeanServer.getAttribute(objectName, testAttributeName)).thenReturn(null); jmxSensor.mbeanServerAdded(mBeanServer); jmxSensor.update(coreService); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).getAttribute(objectName, testAttributeName); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); ArgumentCaptor<JmxSensorValueData> valueCaptor = ArgumentCaptor.forClass(JmxSensorValueData.class); verify(coreService).addJmxSensorValueData(eq(sensorType), eq(testObjectName), eq(testAttributeName), valueCaptor.capture()); assertThat(valueCaptor.getValue().getPlatformIdent(), is(equalTo(platformIdent))); assertThat(valueCaptor.getValue().getSensorTypeIdent(), is(equalTo(sensorType))); assertThat(valueCaptor.getValue().getJmxSensorDefinitionDataIdentId(), is(equalTo(definitionDataIdentId))); assertThat(valueCaptor.getValue().getValue(), is("null")); } @Test public void collectDataPrimitiveArray() throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), Matchers.<Collection<JmxAttributeDescriptor>> any())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); when(mBeanServer.getAttribute(objectName, testAttributeName)).thenReturn(new int[] { 1, 2, 3 }); jmxSensor.mbeanServerAdded(mBeanServer); jmxSensor.update(coreService); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).getAttribute(objectName, testAttributeName); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); ArgumentCaptor<JmxSensorValueData> valueCaptor = ArgumentCaptor.forClass(JmxSensorValueData.class); verify(coreService).addJmxSensorValueData(eq(sensorType), eq(testObjectName), eq(testAttributeName), valueCaptor.capture()); assertThat(valueCaptor.getValue().getPlatformIdent(), is(equalTo(platformIdent))); assertThat(valueCaptor.getValue().getSensorTypeIdent(), is(equalTo(sensorType))); assertThat(valueCaptor.getValue().getJmxSensorDefinitionDataIdentId(), is(equalTo(definitionDataIdentId))); assertThat(valueCaptor.getValue().getValue(), is("[1, 2, 3]")); } @Test public void collectDataObjectArray() throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), Matchers.<Collection<JmxAttributeDescriptor>> any())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); when(mBeanServer.getAttribute(objectName, testAttributeName)).thenReturn(new String[] { "1", "2", "3" }); jmxSensor.mbeanServerAdded(mBeanServer); jmxSensor.update(coreService); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).getAttribute(objectName, testAttributeName); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), Matchers.<NotificationListener> any(), Matchers.<NotificationFilter> any(), eq(null)); verifyNoMoreInteractions(mBeanServer); ArgumentCaptor<JmxSensorValueData> valueCaptor = ArgumentCaptor.forClass(JmxSensorValueData.class); verify(coreService).addJmxSensorValueData(eq(sensorType), eq(testObjectName), eq(testAttributeName), valueCaptor.capture()); assertThat(valueCaptor.getValue().getPlatformIdent(), is(equalTo(platformIdent))); assertThat(valueCaptor.getValue().getSensorTypeIdent(), is(equalTo(sensorType))); assertThat(valueCaptor.getValue().getJmxSensorDefinitionDataIdentId(), is(equalTo(definitionDataIdentId))); assertThat(valueCaptor.getValue().getValue(), is("[1, 2, 3]")); } @DataProvider(name = "throwableProvider") public Object[][] getThrowables() { return new Object[][] { { AttributeNotFoundException.class }, { InstanceNotFoundException.class }, { MBeanException.class }, { ReflectionException.class }, { RuntimeMBeanException.class } }; } } public static class HandleNotification extends JmxSensorTest { @BeforeMethod public void init() { jmxSensor.init(sensorTypeConfig); } @Test public void registrationNotification() throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String value = "value"; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); jmxSensor.mbeanServerAdded(mBeanServer); ArgumentCaptor<MBeanServerHolder> notificationListener = ArgumentCaptor.forClass(MBeanServerHolder.class); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), notificationListener.capture(), Matchers.<NotificationFilter> any(), eq(null)); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); ArgumentCaptor<Collection> captor = ArgumentCaptor.forClass(Collection.class); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), captor.capture())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); when(mBeanServer.getAttribute(objectName, testAttributeName)).thenReturn(value); MBeanServerNotification notification = new MBeanServerNotification(MBeanServerNotification.REGISTRATION_NOTIFICATION, this, 1, objectName); notificationListener.getValue().handleNotification(notification, null); jmxSensor.update(coreService); JmxAttributeDescriptor sensorConfig = (JmxAttributeDescriptor) captor.getValue().iterator().next(); assertThat(sensorConfig.getId(), is(equalTo(definitionDataIdentId))); assertThat(sensorConfig.getmBeanObjectName(), is(equalTo(testObjectName))); assertThat(sensorConfig.getAttributeName(), is(equalTo(testAttributeName))); assertThat(sensorConfig.getmBeanAttributeDescription(), is(equalTo(testAttrDescription))); assertThat(sensorConfig.getmBeanAttributeType(), is(equalTo(testAttrType))); assertThat(sensorConfig.ismBeanAttributeIsIs(), is(equalTo(testAttrIsIs))); assertThat(sensorConfig.ismBeanAttributeIsReadable(), is(equalTo(testAttrIsReadable))); assertThat(sensorConfig.ismBeanAttributeIsWritable(), is(equalTo(testAttrIsWriteable))); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verify(mBeanServer).getAttribute(objectName, testAttributeName); verifyNoMoreInteractions(mBeanServer); ArgumentCaptor<JmxSensorValueData> valueCaptor = ArgumentCaptor.forClass(JmxSensorValueData.class); verify(coreService).addJmxSensorValueData(eq(sensorType), eq(testObjectName), eq(testAttributeName), valueCaptor.capture()); assertThat(valueCaptor.getValue().getPlatformIdent(), is(equalTo(platformIdent))); assertThat(valueCaptor.getValue().getSensorTypeIdent(), is(equalTo(sensorType))); assertThat(valueCaptor.getValue().getJmxSensorDefinitionDataIdentId(), is(equalTo(definitionDataIdentId))); assertThat(valueCaptor.getValue().getValue(), is(value)); } @Test public void unregistrationNotification() throws Exception { long sensorType = 13L; long platformIdent = 11L; final long definitionDataIdentId = 17L; String testObjectName = "Testdomain:Test=TestObjectName,name=test"; String testAttributeName = "TestAttributename"; String testAttrDescription = "test-description"; String testAttrType = "test-type"; boolean testAttrIsReadable = true; boolean testAttrIsWriteable = false; boolean testAttrIsIs = false; MBeanAttributeInfo mBeanAttributeInfo = new MBeanAttributeInfo(testAttributeName, testAttrType, testAttrDescription, testAttrIsReadable, testAttrIsWriteable, testAttrIsIs); MBeanAttributeInfo[] mBeanAttributeInfos = { mBeanAttributeInfo }; ObjectName objectName = new ObjectName(testObjectName); when(sensorTypeConfig.getId()).thenReturn(sensorType); when(mBeanServer.queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null))).thenReturn(Collections.singleton(objectName)); when(mBeanServer.getMBeanInfo(Matchers.<ObjectName> any())).thenReturn(mBeanInfo); when(mBeanInfo.getAttributes()).thenReturn(mBeanAttributeInfos); when(platformManager.getPlatformId()).thenReturn(platformIdent); when(connection.isConnected()).thenReturn(true); when(connection.analyzeJmxAttributes(eq(platformIdent), Matchers.<Collection<JmxAttributeDescriptor>> any())).thenAnswer(new Answer<Collection<JmxAttributeDescriptor>>() { @Override public Collection<JmxAttributeDescriptor> answer(InvocationOnMock invocation) throws Throwable { Collection<JmxAttributeDescriptor> descriptors = (Collection<JmxAttributeDescriptor>) invocation.getArguments()[1]; for (JmxAttributeDescriptor d : descriptors) { d.setId(definitionDataIdentId); } return descriptors; } }); MBeanServerNotification notification = new MBeanServerNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION, this, 1, objectName); jmxSensor.mbeanServerAdded(mBeanServer); ArgumentCaptor<MBeanServerHolder> notificationListener = ArgumentCaptor.forClass(MBeanServerHolder.class); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), notificationListener.capture(), Matchers.<NotificationFilter> any(), eq(null)); notificationListener.getValue().handleNotification(notification, null); jmxSensor.update(coreService); verify(mBeanServer).queryNames(Matchers.<ObjectName> any(), (QueryExp) eq(null)); verify(mBeanServer).getMBeanInfo(objectName); verifyNoMoreInteractions(mBeanServer); verifyZeroInteractions(coreService); } @Test public void wrongNotification() throws Exception { jmxSensor.mbeanServerAdded(mBeanServer); ArgumentCaptor<MBeanServerHolder> notificationListener = ArgumentCaptor.forClass(MBeanServerHolder.class); verify(mBeanServer).addNotificationListener(Matchers.<ObjectName> any(), notificationListener.capture(), Matchers.<NotificationFilter> any(), eq(null)); Notification notification = mock(Notification.class); when(connection.isConnected()).thenReturn(true); notificationListener.getValue().handleNotification(notification, null); verifyZeroInteractions(mBeanServer); } } }