org.apache.brooklyn.api.sensor.SensorEvent Java Examples
The following examples show how to use
org.apache.brooklyn.api.sensor.SensorEvent.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ServiceRestarter.java From brooklyn-server with Apache License 2.0 | 6 votes |
protected synchronized void onDetectedFailure(SensorEvent<Object> event) { if (isSuspended()) { highlightViolation("Failure detected but policy suspended"); LOG.warn("ServiceRestarter suspended, so not acting on failure detected at "+entity+" ("+event.getValue()+")"); return; } LOG.warn("ServiceRestarter acting on failure detected at "+entity+" ("+event.getValue()+")"); long current = System.currentTimeMillis(); Long last = lastFailureTime.getAndSet(current); long elapsed = last==null ? -1 : current-last; if (elapsed>=0 && elapsed <= getConfig(FAIL_ON_RECURRING_FAILURES_IN_THIS_DURATION).toMilliseconds()) { highlightViolation("Failure detected but policy ran "+Duration.millis(elapsed)+" ago (cannot run again within "+getConfig(FAIL_ON_RECURRING_FAILURES_IN_THIS_DURATION)+")"); onRestartFailed("Restart failure (failed again after "+Time.makeTimeStringRounded(elapsed)+") at "+entity+": "+event.getValue()); return; } try { highlightViolation("Failure detected and restart triggered"); ServiceStateLogic.setExpectedState(entity, Lifecycle.STARTING); Task<Void> t = Entities.invokeEffector(entity, entity, Startable.RESTART); highlightAction("Restart node on failure", t); t.get(); } catch (Exception e) { onRestartFailed("Restart failure (error "+e+") at "+entity+": "+event.getValue()); } }
Example #2
Source File: LocalSubscriptionManagerTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testSubscribeToMemberAttributeChange() throws Exception { BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class)); TestEntity member = app.createAndManageChild(EntitySpec.create(TestEntity.class)); group.addMember(member); final List<SensorEvent<Integer>> events = new CopyOnWriteArrayList<SensorEvent<Integer>>(); final CountDownLatch latch = new CountDownLatch(1); app.subscriptions().subscribeToMembers(group, TestEntity.SEQUENCE, new SensorEventListener<Integer>() { @Override public void onEvent(SensorEvent<Integer> event) { events.add(event); latch.countDown(); }}); member.sensors().set(TestEntity.SEQUENCE, 123); if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) { fail("Timeout waiting for Event on parent TestEntity listener"); } assertEquals(events.size(), 1); assertEquals(events.get(0).getValue(), (Integer)123); assertEquals(events.get(0).getSensor(), TestEntity.SEQUENCE); assertEquals(events.get(0).getSource().getId(), member.getId()); }
Example #3
Source File: LocalEntitiesTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testEffectorEmitsTransientSensor() throws Exception { HelloEntity h = app.createAndManageChild(EntitySpec.create(HelloEntity.class)); app.start(ImmutableList.of(loc)); final AtomicReference<SensorEvent<?>> evt = new AtomicReference<SensorEvent<?>>(); app.subscriptions().subscribe(h, HelloEntity.ITS_MY_BIRTHDAY, new SensorEventListener<Object>() { @Override public void onEvent(SensorEvent<Object> event) { evt.set(event); synchronized (evt) { evt.notifyAll(); } }}); long startTime = System.currentTimeMillis(); synchronized (evt) { h.setAge(5); evt.wait(5000); } assertNotNull(evt.get()); assertEquals(HelloEntity.ITS_MY_BIRTHDAY, evt.get().getSensor()); assertEquals(h, evt.get().getSource()); assertNull(evt.get().getValue()); assertTrue(System.currentTimeMillis() - startTime < 5000); //shouldn't have blocked for all 5s }
Example #4
Source File: SensorPropagatingEnricherTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testPropagatesAllSensorsIncludesDynamicallyAdded() { AttributeSensor<String> dynamicAttribute = Sensors.newStringSensor("test.dynamicsensor.strattrib"); BasicNotificationSensor<String> dynamicNotificationSensor = new BasicNotificationSensor<String>(String.class, "test.dynamicsensor.strnotif"); app.enrichers().add(Enrichers.builder() .propagatingAll() .from(entity) .build()); entity.sensors().set(dynamicAttribute, "foo"); EntityAsserts.assertAttributeEqualsEventually(app, dynamicAttribute, "foo"); // notification-sensor propagated final AtomicReference<String> notif = new AtomicReference<String>(); app.subscriptions().subscribe(app, dynamicNotificationSensor, new SensorEventListener<String>() { @Override public void onEvent(SensorEvent<String> event) { notif.set(event.getValue()); }}); entity.sensors().emit(dynamicNotificationSensor, "mynotifval"); Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo("mynotifval")); }
Example #5
Source File: ItemsInContainersGroupImpl.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Override public void onEvent(SensorEvent<Object> event) { Entity source = event.getSource(); Object value = event.getValue(); Sensor sensor = event.getSensor(); if (sensor.equals(AbstractGroup.MEMBER_ADDED)) { onContainerAdded((Entity) value); } else if (sensor.equals(AbstractGroup.MEMBER_REMOVED)) { onContainerRemoved((Entity) value); } else if (sensor.equals(Movable.CONTAINER)) { onItemMoved((Movable)source, (BalanceableContainer<?>) value); } else { throw new IllegalStateException("Unhandled event type "+sensor+": "+event); } }
Example #6
Source File: SensorPropagatingEnricherTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testPropagatesAllStaticSensors() { app.enrichers().add(Enrichers.builder() .propagatingAll() .from(entity) .build()); // all attributes propagated entity.sensors().set(TestEntity.NAME, "foo"); entity.sensors().set(TestEntity.SEQUENCE, 2); EntityAsserts.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); EntityAsserts.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2); // notification-sensor propagated final AtomicReference<Integer> notif = new AtomicReference<Integer>(); app.subscriptions().subscribe(app, TestEntity.MY_NOTIF, new SensorEventListener<Integer>() { @Override public void onEvent(SensorEvent<Integer> event) { notif.set(event.getValue()); }}); entity.sensors().emit(TestEntity.MY_NOTIF, 7); Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo(7)); }
Example #7
Source File: Propagator.java From brooklyn-server with Apache License 2.0 | 6 votes |
@SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void onEvent(SensorEvent<Object> event) { // propagate upwards Sensor<?> sourceSensor = event.getSensor(); Sensor<?> destinationSensor = getDestinationSensor(sourceSensor); if (!sensorFilter.apply(sourceSensor)) { return; // ignoring excluded sensor } if (LOG.isTraceEnabled()) LOG.trace("enricher {} got {}, propagating via {}{}", new Object[] {this, event, entity, (sourceSensor == destinationSensor ? "" : " (as "+destinationSensor+")")}); emit((Sensor)destinationSensor, event.getValue()); }
Example #8
Source File: RollingTimeWindowMeanEnricher.java From brooklyn-server with Apache License 2.0 | 6 votes |
public void onEvent(SensorEvent<T> event, long eventTime) { values.addLast(event.getValue()); timestamps.addLast(eventTime); if (eventTime>0) { ConfidenceQualifiedNumber average = getAverage(eventTime, 0); if (average.confidence > getConfig(CONFIDENCE_REQUIRED_TO_PUBLISH)) { // without confidence, we might publish wildly varying estimates, // causing spurious resizes, so allow it to be configured, and // by default require a high value // TODO would be nice to include timestamp, etc entity.sensors().set((AttributeSensor<Double>)target, average.value); } } }
Example #9
Source File: DynamicGroupImpl.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public <T> void addSubscription(Entity producer, Sensor<T> sensor, final Predicate<? super SensorEvent<? super T>> filter) { SensorEventListener<T> listener = new SensorEventListener<T>() { @Override public void onEvent(SensorEvent<T> event) { if (filter.apply(event)) onEntityChanged(event.getSource()); } }; subscriptions().subscribe(producer, sensor, listener); }
Example #10
Source File: AbstractEntity.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public <T> void emit(Sensor<T> sensor, T val) { if (sensor instanceof AttributeSensor) { LOG.warn("Strongly discouraged use of emit with attribute sensor "+sensor+" "+val+"; use setAttribute instead!", new Throwable("location of discouraged attribute "+sensor+" emit")); } if (val instanceof SensorEvent) { LOG.warn("Strongly discouraged use of emit with sensor event as value "+sensor+" "+val+"; value should be unpacked!", new Throwable("location of discouraged event "+sensor+" emit")); } BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(AbstractEntity.this), "Emitting sensor notification {} value {} on {}", sensor.getName(), val, AbstractEntity.this); emitInternal(sensor, val); }
Example #11
Source File: ServiceStateLogic.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public void onEvent(@Nullable SensorEvent<Object> event) { Preconditions.checkNotNull(entity, "Cannot handle subscriptions or compute state until associated with an entity"); Map<String, Object> serviceProblems = entity.getAttribute(SERVICE_PROBLEMS); Boolean serviceUp = entity.getAttribute(SERVICE_UP); Lifecycle.Transition serviceExpected = entity.getAttribute(SERVICE_STATE_EXPECTED); if (serviceExpected!=null && serviceExpected.getState()==Lifecycle.RUNNING) { setActualState( computeActualStateWhenExpectedRunning(serviceProblems, serviceUp) ); } else { setActualState( computeActualStateWhenNotExpectedRunning(serviceProblems, serviceUp, serviceExpected) ); } }
Example #12
Source File: InvokeEffectorOnSensorChange.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public void onEvent(SensorEvent<Object> event) { final Effector<?> eff = getEffectorNamed(getConfig(EFFECTOR)).get(); if (isBusySensorEnabled()) { final Object currentSensorValue = entity.sensors().get(sensor); setMoreUpdatesComing(event.getTimestamp(), event.getValue(), currentSensorValue); } invoke(eff, MutableMap.<String, Object>of()); }
Example #13
Source File: PercentageEnricher.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public void onEvent(SensorEvent<Number> event) { Number current = producer.sensors().get(sourceCurrentSensor); if (current == null) { LOG.trace("Can't calculate percentage value for entity {} as current from producer {} is null", entity, producer); return; } Number total = producer.sensors().get(sourceTotalSensor); if (total == null) { LOG.trace("Can't calculate percentage value for entity {} as total from producer {} is null", entity, producer); return; } Double currentDouble = current.doubleValue(); Double totalDouble = total.doubleValue(); if (DoubleMath.fuzzyEquals(totalDouble, 0d, EPSILON)) { LOG.trace("Can't calculate percentage value for entity {} as total from producer {} is zero", entity, producer); return; } if (currentDouble < 0d || totalDouble < 0d) { LOG.trace("Can't calculate percentage value for entity {} as current ({}) or total ({}) from producer {} is negative", new Object[] { entity, currentDouble, totalDouble, producer }); return; } Double result = currentDouble / totalDouble; emit(targetSensor, result); }
Example #14
Source File: YamlTimeWeightedDeltaEnricher.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override protected Function<SensorEvent<T>, Double> getTransformation() { return new Function<SensorEvent<T>, Double>() { @Override public Double apply(SensorEvent<T> event) { synchronized (lock) { Double current = TypeCoercions.coerce(event.getValue(), Double.class); if (current == null) return null; long eventTime = event.getTimestamp(); long unitMillis = getConfig(DELTA_PERIOD).toMilliseconds(); Double result = null; if (eventTime > 0 && eventTime > lastTime) { if (lastValue == null || lastTime < 0) { // cannot calculate time-based delta with a single value if (LOG.isTraceEnabled()) LOG.trace("{} received event but no last value so will not emit, null -> {} at {}", new Object[] {this, current, eventTime}); } else { double duration = eventTime - lastTime; result = (current - lastValue.doubleValue()) / (duration / unitMillis); } } lastValue = current; lastTime = eventTime; return result; } } }; }
Example #15
Source File: AbstractTransformer.java From brooklyn-server with Apache License 2.0 | 5 votes |
protected Object compute(SensorEvent<T> event) { // transformation is not going to change, but this design makes it easier to support changing config in future. // if it's an efficiency hole we can switch to populate the transformation at start. U result = getTransformation().apply(event); if (LOG.isTraceEnabled()) LOG.trace("Enricher "+this+" computed "+result+" from "+event); return result; }
Example #16
Source File: HaPolicyRebindTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
private void assertHasEvent(Sensor<?> sensor, Predicate<Object> componentPredicate, Predicate<? super CharSequence> descriptionPredicate) { for (SensorEvent<FailureDescriptor> event : events) { if (event.getSensor().equals(sensor) && (componentPredicate == null || componentPredicate.apply(event.getValue().getComponent())) && (descriptionPredicate == null || descriptionPredicate.apply(event.getValue().getDescription()))) { return; } } fail("No matching "+sensor+" event found; events="+events); }
Example #17
Source File: InvokeEffectorOnCollectionSensorChangeTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Test public void testPublishesIsBusySensor() { final List<Boolean> isBusyValues = new CopyOnWriteArrayList<>(); testEntity.subscriptions().subscribe(testEntity, IS_BUSY_SENSOR, new SensorEventListener<Boolean>() { @Override public void onEvent(SensorEvent<Boolean> event) { isBusyValues.add(event.getValue()); } }); addSetChangePolicy(true, false); testEntity.sensors().set(DEFAULT_SENSOR, ImmutableSet.of(1)); List<Boolean> expected = ImmutableList.of(false, true, false); Asserts.eventually(Suppliers.ofInstance(isBusyValues), Predicates.equalTo(expected)); }
Example #18
Source File: YamlRollingTimeWindowMeanEnricher.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override protected Function<SensorEvent<T>, Double> getTransformation() { return new Function<SensorEvent<T>, Double>() { @Override public Double apply(SensorEvent<T> event) { long eventTime = event.getTimestamp(); if (event.getValue()==null) { return null; } values.addLast(event.getValue()); timestamps.addLast(eventTime); if (eventTime>0) { ConfidenceQualifiedNumber average = getAverage(eventTime, 0); if (average.confidence > getConfig(CONFIDENCE_REQUIRED_TO_PUBLISH)) { // without confidence, we might publish wildly varying estimates, // causing spurious resizes, so allow it to be configured, and // by default require a high value // TODO would be nice to include timestamp, etc return average.value; } } return null; } }; }
Example #19
Source File: CassandraFabricImpl.java From brooklyn-library with Apache License 2.0 | 5 votes |
protected void connectEnrichers() { // TODO Aggregate across sub-clusters subscriptions().subscribeToMembers(this, SERVICE_UP, new SensorEventListener<Boolean>() { @Override public void onEvent(SensorEvent<Boolean> event) { sensors().set(SERVICE_UP, calculateServiceUp()); } }); }
Example #20
Source File: AbstractSubscriptionManager.java From brooklyn-server with Apache License 2.0 | 5 votes |
/** @see SubscriptionManager#subscribe(Map, Entity, Sensor, SensorEventListener) */ @Override public final <T> SubscriptionHandle subscribeToMembers(Map<String, Object> flags, final Group parent, Sensor<T> sensor, SensorEventListener<? super T> listener) { Predicate<SensorEvent<T>> eventFilter = new Predicate<SensorEvent<T>>() { @Override public boolean apply(SensorEvent<T> input) { return parent.getMembers().contains(input.getSource()); } }; flags.put("eventFilter", eventFilter); return subscribe(flags, null, sensor, listener); }
Example #21
Source File: RecordingSensorEventListener.java From brooklyn-server with Apache License 2.0 | 5 votes |
public void assertHasEventEventually(final Predicate<? super SensorEvent<T>> filter) { Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertHasEvent(filter); }}); }
Example #22
Source File: ServiceRestarterTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override @BeforeMethod(alwaysRun=true) public void setUp() throws Exception { super.setUp(); e1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); events = Lists.newCopyOnWriteArrayList(); eventListener = new SensorEventListener<Object>() { @Override public void onEvent(SensorEvent<Object> event) { events.add(event); } }; }
Example #23
Source File: LocalEntitiesTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Test public void testSendMultipleInOrderThenUnsubscribe() throws Exception { HelloEntity h = app.createAndManageChild(EntitySpec.create(HelloEntity.class)); app.start(ImmutableList.of(loc)); final List<Integer> data = Lists.newArrayList(); final CountDownLatch latch = new CountDownLatch(5); app.subscriptions().subscribe(h, HelloEntity.AGE, new SensorEventListener<Integer>() { @Override public void onEvent(SensorEvent<Integer> event) { data.add(event.getValue()); Time.sleep((int)(20*Math.random())); log.info("Thread "+Thread.currentThread()+" notify on subscription received for "+event.getValue()+", data is "+data); latch.countDown(); }}); Stopwatch stopwatch = Stopwatch.createStarted(); for (int i = 1; i <= 5; i++) { h.setAge(i); } assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); app.subscriptions().unsubscribeAll(); h.setAge(6); long totalTime = stopwatch.elapsed(TimeUnit.MILLISECONDS); Asserts.continually( Suppliers.ofInstance(data), Predicates.<Object>equalTo(ImmutableList.of(1,2,3,4,5)), Duration.millis(50), null, null); assertTrue(totalTime < 2000, "totalTime="+totalTime); //shouldn't have blocked for anywhere close to 2s (unless build machine v v slow eg BuildHive) }
Example #24
Source File: HaPolicyRebindTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override @BeforeMethod(alwaysRun=true) public void setUp() throws Exception { super.setUp(); origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class)); events = Lists.newCopyOnWriteArrayList(); eventListener = new SensorEventListener<FailureDescriptor>() { @Override public void onEvent(SensorEvent<FailureDescriptor> event) { events.add(event); } }; }
Example #25
Source File: AbstractScheduledEffectorPolicy.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public void onEvent(SensorEvent<Object> event) { LOG.debug("{}: Got event {}", this, event); AttributeSensor<Boolean> sensor = config().get(START_SENSOR); if (event.getSensor().getName().equals(sensor.getName())) { Boolean start = Boolean.TRUE.equals(event.getValue()); if (start && running.compareAndSet(false, true)) { config().set(RUNNING, true); start(); } } }
Example #26
Source File: StopAfterDurationPolicy.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public void onEvent(SensorEvent<Duration> event) { synchronized (eventLock) { if (!config().get(FIRED_STOP)) { if (config().get(LIFETIME).subtract(event.getValue()).isNegative()) { LOG.debug("Stopping {}: lifetime ({}) has expired", entity, config().get(LIFETIME)); entity.invoke(Startable.STOP, ImmutableMap.<String, Object>of()); config().set(FIRED_STOP, true); } } } }
Example #27
Source File: DynamicClusterTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Test public void defaultRemovalStrategyShutsDownNewestFirstWhenResizing() throws Exception { final List<Entity> creationOrder = Lists.newArrayList(); DynamicCluster cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class) .configure("initialSize", 0) .configure("memberSpec", EntitySpec.create(TestEntity.class))); cluster.subscriptions().subscribe(cluster, AbstractEntity.CHILD_ADDED, new SensorEventListener<Entity>() { @Override public void onEvent(SensorEvent<Entity> event) { if (event.getValue() instanceof TestEntity) { creationOrder.add(event.getValue()); } }}); cluster.start(ImmutableList.of(loc)); cluster.resize(1); //Prevent the two entities created in the same ms //so that the removal strategy can always choose the //entity created next Thread.sleep(1); cluster.resize(2); Asserts.eventually(Suppliers.ofInstance(creationOrder), CollectionFunctionals.sizeEquals(2)); assertEquals(cluster.getCurrentSize(), (Integer)2); assertEquals(ImmutableSet.copyOf(cluster.getMembers()), ImmutableSet.copyOf(creationOrder), "actual="+cluster.getMembers()); // Now stop one cluster.resize(1); assertEquals(cluster.getCurrentSize(), (Integer)1); assertEquals(ImmutableList.copyOf(cluster.getMembers()), creationOrder.subList(0, 1)); }
Example #28
Source File: FollowTheSunPoolImpl.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public void onEvent(SensorEvent<Object> event) { if (LOG.isTraceEnabled()) LOG.trace("{} received event {}", FollowTheSunPoolImpl.this, event); Entity source = event.getSource(); Object value = event.getValue(); Sensor<?> sensor = event.getSensor(); if (sensor.equals(AbstractGroup.MEMBER_ADDED)) { if (source.equals(containerGroup)) { onContainerAdded((Entity) value); } else if (source.equals(itemGroup)) { onItemAdded((Entity)value); } else { throw new IllegalStateException("unexpected event source="+source); } } else if (sensor.equals(AbstractGroup.MEMBER_REMOVED)) { if (source.equals(containerGroup)) { onContainerRemoved((Entity) value); } else if (source.equals(itemGroup)) { onItemRemoved((Entity) value); } else { throw new IllegalStateException("unexpected event source="+source); } } else if (sensor.equals(Startable.SERVICE_UP)) { // TODO What if start has failed? Is there a sensor to indicate that? if ((Boolean)value) { onContainerUp(source); } else { onContainerDown(source); } } else if (sensor.equals(Movable.CONTAINER)) { onItemMoved(source, (Entity) value); } else { throw new IllegalStateException("Unhandled event type "+sensor+": "+event); } }
Example #29
Source File: QueueingSubscriptionManager.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public synchronized <T> void publish(SensorEvent<T> event) { if (useDelegateForPublishing) { delegate.publish(event); return; } queuedSensorEvents.add(event); }
Example #30
Source File: ServiceRestarter.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Override public void setEntity(final EntityLocal entity) { Preconditions.checkArgument(entity instanceof Startable, "Restarter must take a Startable, not "+entity); super.setEntity(entity); subscriptions().subscribe(entity, getConfig(FAILURE_SENSOR_TO_MONITOR), new SensorEventListener<Object>() { @Override public void onEvent(final SensorEvent<Object> event) { // Must execute in another thread - if we called entity.restart in the event-listener's thread // then we'd block all other events being delivered to this entity's other subscribers. // Relies on synchronization of `onDetectedFailure`. // See same pattern used in ServiceReplacer. // TODO Could use BasicExecutionManager.setTaskSchedulerForTag to prevent race of two // events being received in rapid succession, and onDetectedFailure being executed out-of-order // for them; or could write events to a blocking queue and have onDetectedFailure read from that. if (isRunning()) { LOG.info("ServiceRestarter notified; dispatching job for "+entity+" ("+event.getValue()+")"); getExecutionContext().submit("Analyzing detected failure", () -> onDetectedFailure(event)); } else { LOG.warn("ServiceRestarter not running, so not acting on failure detected at "+entity+" ("+event.getValue()+")"); } } }); highlightTriggers(getConfig(FAILURE_SENSOR_TO_MONITOR), entity); }