JmxAttributeSensor extends AbstractAddSensorFeed<T> { @Override public void apply(final EntityLocal entity) { AttributeSensor<T> sensor = addSensor(entity); ConfigBag params = initParams(); String objectName = Preconditions.checkNotNull(params.get(OBJECT_NAME), "objectName"); String attribute = Preconditions.checkNotNull(params.get(ATTRIBUTE), "attribute"); Object defaultValue = params.get(DEFAULT_VALUE); try { ObjectName.getInstance(objectName); } catch (MalformedObjectNameException mone) { throw new IllegalArgumentException("Malformed JMX object name: " + objectName, mone); } final Boolean suppressDuplicates = EntityInitializers.resolve(params, SUPPRESS_DUPLICATES); final Duration logWarningGraceTimeOnStartup = EntityInitializers.resolve(params, LOG_WARNING_GRACE_TIME_ON_STARTUP); final Duration logWarningGraceTime = EntityInitializers.resolve(params, LOG_WARNING_GRACE_TIME); if (entity instanceof UsesJmx) { if (LOG.isDebugEnabled()) { LOG.debug("Submitting task to add JMX sensor {} to {}", params.get(SENSOR_NAME), entity); } Task<Integer> jmxPortTask = DependentConfiguration.attributeWhenReady(entity, UsesJmx.JMX_PORT); Task<JmxFeed> jmxFeedTask = Tasks.<JmxFeed>builder() .description("Add JMX feed") .body(new Callable<JmxFeed>() { @Override public JmxFeed call() throws Exception { JmxHelper helper = new JmxHelper(entity); JmxFeed feed = JmxFeed.builder() .entity(entity) .period(params.get(SENSOR_PERIOD)) .helper(helper) .pollAttribute(new JmxAttributePollConfig<T>(sensor) .objectName(objectName) .attributeName(attribute) .suppressDuplicates(Boolean.TRUE.equals(suppressDuplicates)) .onFailureOrException(Functions.<T>constant((T) defaultValue)) .logWarningGraceTimeOnStartup(logWarningGraceTimeOnStartup) .logWarningGraceTime(logWarningGraceTime)) .build(); entity.addFeed(feed); return feed; } }) .build(); DynamicTasks.submit(Tasks.sequential("Add JMX Sensor " + sensor.getName(), jmxPortTask, jmxFeedTask), entity); } else { throw new IllegalStateException(String.format("Entity %s does not support JMX", entity)); } } protected  JmxAttributeSensor();  JmxAttributeSensor(final ConfigBag params); @Override void apply(final EntityLocal entity); static final ConfigKey<String> OBJECT_NAME; static final ConfigKey<String> ATTRIBUTE; static final ConfigKey<Object> DEFAULT_VALUE; }
@Test public void testSensor() throws Exception { GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, 42), objectName); JmxAttributeSensor<Integer> sensor = new JmxAttributeSensor<Integer>(ConfigBag.newInstance() .configure(JmxAttributeSensor.SENSOR_PERIOD, Duration.millis(10)) .configure(JmxAttributeSensor.SENSOR_NAME, SENSOR_STRING.getName()) .configure(JmxAttributeSensor.SENSOR_TYPE, STRING_TARGET_TYPE) .configure(JmxAttributeSensor.OBJECT_NAME, objectName) .configure(JmxAttributeSensor.ATTRIBUTE, attributeName)); sensor.apply(entity); entity.sensors().set(Attributes.SERVICE_UP, true); EntityAsserts.assertAttributeEqualsEventually(entity, SENSOR_STRING, "42"); mbean.updateAttributeValue(attributeName, 64); EntityAsserts.assertAttributeEqualsEventually(entity, SENSOR_STRING, "64"); }
@Test(groups="Integration") public void testSensorSupressingDuplicates() throws Exception { GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, 42), objectName); RecordingSensorEventListener<String> listener = new RecordingSensorEventListener<>(); entity.subscriptions().subscribe(entity, SENSOR_STRING, listener); JmxAttributeSensor<Integer> sensor = new JmxAttributeSensor<Integer>(ConfigBag.newInstance() .configure(HttpRequestSensor.SUPPRESS_DUPLICATES, true) .configure(JmxAttributeSensor.SENSOR_PERIOD, Duration.millis(10)) .configure(JmxAttributeSensor.SENSOR_NAME, SENSOR_STRING.getName()) .configure(JmxAttributeSensor.SENSOR_TYPE, STRING_TARGET_TYPE) .configure(JmxAttributeSensor.OBJECT_NAME, objectName) .configure(JmxAttributeSensor.ATTRIBUTE, attributeName)); sensor.apply(entity); entity.sensors().set(Attributes.SERVICE_UP, true); EntityAsserts.assertAttributeEqualsEventually(entity, SENSOR_STRING, "42"); listener.assertHasEventEventually(Predicates.alwaysTrue()); Asserts.succeedsContinually(new Runnable() { @Override public void run() { listener.assertEventCount(1); }}); EntityAsserts.assertAttributeEqualsEventually(entity, SENSOR_STRING, "42"); mbean.updateAttributeValue(attributeName, 64); EntityAsserts.assertAttributeEqualsEventually(entity, SENSOR_STRING, "64"); }