@Test public void testJmxNotificationSubscriptionForSensorParsingNotification() throws Exception { final String one = "notification.one", two = "notification.two"; final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName); final AtomicInteger sequence = new AtomicInteger(0); feed = JmxFeed.builder() .entity(entity) .subscribeToNotification( new JmxNotificationSubscriptionConfig<Integer>(intAttribute) .objectName(objectName) .notificationFilter(JmxNotificationFilters.matchesType(one)) .onNotification( new Function<Notification, Integer>() { public Integer apply(Notification notif) { return (Integer) notif.getUserData(); } })) .build(); // Notification updates the sensor // Note that subscription is done async, so can't just send notification immediately during // test. Asserts.succeedsEventually( ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() { public void run() { sendNotification(mbean, one, sequence.getAndIncrement(), 123); assertEquals(entity.getAttribute(intAttribute), (Integer) 123); } }); }
@Test public void testJmxNotificationMultipleSubscriptionUsingListener() throws Exception { final String one = "notification.one"; final String two = "notification.two"; final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName); final AtomicInteger sequence = new AtomicInteger(0); feed = JmxFeed.builder() .entity(entity) .subscribeToNotification( new JmxNotificationSubscriptionConfig<Integer>(intAttribute) .objectName(objectName) .notificationFilter(JmxNotificationFilters.matchesTypes(one, two))) .build(); // Notification updates the sensor // Note that subscription is done async, so can't just send notification immediately during // test. Asserts.succeedsEventually( ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() { public void run() { sendNotification(mbean, one, sequence.getAndIncrement(), 123); assertEquals(entity.getAttribute(intAttribute), (Integer) 123); } }); // And wildcard means other notifications also received sendNotification(mbean, two, sequence.getAndIncrement(), 456); assertSensorEventually(intAttribute, 456, TIMEOUT_MS); }
@Test public void testJmxOperationWithArgPolledForSensor() throws Exception { // This is awful syntax... MBeanParameterInfo paramInfo = new MBeanParameterInfo("param1", String.class.getName(), "my param1"); MBeanParameterInfo[] paramInfos = new MBeanParameterInfo[] {paramInfo}; MBeanOperationInfo opInfo = new MBeanOperationInfo( opName, "my descr", paramInfos, String.class.getName(), MBeanOperationInfo.ACTION); GeneralisedDynamicMBean mbean = jmxService.registerMBean( Collections.emptyMap(), ImmutableMap.of( opInfo, new Function<Object[], String>() { public String apply(Object[] args) { return args[0] + "suffix"; } }), objectName); feed = JmxFeed.builder() .entity(entity) .pollOperation( new JmxOperationPollConfig<String>(stringAttribute) .objectName(objectName) .operationName(opName) .operationParams(ImmutableList.of("myprefix"))) .build(); assertSensorEventually(stringAttribute, "myprefix" + "suffix", TIMEOUT_MS); }
@AfterMethod(alwaysRun = true) public void tearDown() throws Exception { if (feed != null) feed.stop(); if (jmxHelper != null) jmxHelper.disconnect(); if (jmxService != null) jmxService.shutdown(); if (app != null) Entities.destroyAll(app.getManagementContext()); feed = null; }
// Test reproduces functionality used in Monterey, for Venue entity being told of requestActor @Test public void testSubscribeToJmxNotificationAndEmitCorrespondingNotificationSensor() throws Exception { TestApplication app2 = new TestApplicationImpl(); final EntityWithEmitter entity = new EntityWithEmitter(app2); Entities.startManagement(app2); try { app2.start(ImmutableList.of(new SimulatedLocation())); final List<SensorEvent<String>> received = Lists.newArrayList(); app2.subscriptions() .subscribe( null, EntityWithEmitter.MY_NOTIF, new SensorEventListener<String>() { public void onEvent(SensorEvent<String> event) { received.add(event); } }); final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of("one"), objectName); final AtomicInteger sequence = new AtomicInteger(0); jmxHelper.connect(TIMEOUT_MS); jmxHelper.addNotificationListener( jmxObjectName, new NotificationListener() { public void handleNotification(Notification notif, Object callback) { if (notif.getType().equals("one")) { entity.sensors().emit(EntityWithEmitter.MY_NOTIF, (String) notif.getUserData()); } } }); Asserts.succeedsEventually( ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() { public void run() { sendNotification(mbean, "one", sequence.getAndIncrement(), "abc"); assertTrue(received.size() > 0, "received size should be bigger than 0"); assertEquals(received.get(0).getValue(), "abc"); } }); } finally { Entities.destroyAll(app2.getManagementContext()); } }
@Test public void testJmxOperationPolledForSensor() throws Exception { // This is awful syntax... final int opReturnVal = 123; final AtomicInteger invocationCount = new AtomicInteger(); MBeanOperationInfo opInfo = new MBeanOperationInfo( opName, "my descr", new MBeanParameterInfo[0], Integer.class.getName(), MBeanOperationInfo.ACTION); GeneralisedDynamicMBean mbean = jmxService.registerMBean( Collections.emptyMap(), ImmutableMap.of( opInfo, new Function<Object[], Integer>() { public Integer apply(Object[] args) { invocationCount.incrementAndGet(); return opReturnVal; } }), objectName); feed = JmxFeed.builder() .entity(entity) .pollOperation( new JmxOperationPollConfig<Integer>(intAttribute) .objectName(objectName) .operationName(opName)) .build(); Asserts.succeedsEventually( ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() { public void run() { assertTrue(invocationCount.get() > 0, "invocationCount=" + invocationCount); assertEquals(entity.getAttribute(intAttribute), (Integer) opReturnVal); } }); }
@Test public void testJmxAttributeOfTypeTabularDataProviderConvertedToMap() throws Exception { // Create the CompositeType and TabularData CompositeType compositeType = new CompositeType( "typeName", "description", new String[] {"myint", "mystring", "mybool"}, // item names new String[] { "myint", "mystring", "mybool" }, // item descriptions, can't be null or empty string new OpenType<?>[] {SimpleType.INTEGER, SimpleType.STRING, SimpleType.BOOLEAN}); TabularType tt = new TabularType("typeName", "description", compositeType, new String[] {"myint"}); TabularDataSupport tds = new TabularDataSupport(tt); tds.put( new CompositeDataSupport( compositeType, new String[] {"mybool", "myint", "mystring"}, new Object[] {true, 1234, "on"})); // Create MBean GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, tds), objectName); feed = JmxFeed.builder() .entity(entity) .pollAttribute( new JmxAttributePollConfig<Map>(mapAttribute) .objectName(objectName) .attributeName(attributeName) .onSuccess((Function) JmxValueFunctions.tabularDataToMap())) .build(); // Starts with value defined when registering... assertSensorEventually( mapAttribute, ImmutableMap.of("myint", 1234, "mystring", "on", "mybool", Boolean.TRUE), TIMEOUT_MS); }
@Test public void testJmxAttributePollerReturnsMBeanAttribute() throws Exception { GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, 42), objectName); feed = JmxFeed.builder() .entity(entity) .pollAttribute( new JmxAttributePollConfig<Integer>(intAttribute) .objectName(objectName) .period(50) .attributeName(attributeName)) .build(); // Starts with value defined when registering... assertSensorEventually(intAttribute, 42, TIMEOUT_MS); // Change the value and check it updates mbean.updateAttributeValue(attributeName, 64); assertSensorEventually(intAttribute, 64, TIMEOUT_MS); }