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);
 }
  @Override
  public void onEvent(SensorEvent<Object> event) {
    if (firstUpTime == null) {
      if (event != null
          && Attributes.SERVICE_UP.equals(event.getSensor())
          && Boolean.TRUE.equals(event.getValue())) {
        firstUpTime = event.getTimestamp();
      } else if (event == null && Boolean.TRUE.equals(entity.getAttribute(Attributes.SERVICE_UP))) {
        // If this enricher is registered after the entity is up, then we'll get a "synthetic"
        // onEvent(null)
        firstUpTime = System.currentTimeMillis();
      }
    }

    super.onEvent(event);
  }
  public <T> void publish(final SensorEvent<T> event) {
    // REVIEW 1459 - execution

    // delivery in parallel/background, using execution manager

    // subscriptions, should define SingleThreadedScheduler for any subscriber ID tag
    // in order to ensure callbacks are invoked in the order they are submitted
    // (recommend exactly one per subscription to prevent deadlock)
    // this is done with:
    // em.setTaskSchedulerForTag(subscriberId, SingleThreadedScheduler.class);

    // note, generating the notifications must be done in the calling thread to preserve order
    // e.g. emit(A); emit(B); should cause onEvent(A); onEvent(B) in that order
    if (LOG.isTraceEnabled()) LOG.trace("{} got a {} event", this, event);
    totalEventsPublishedCount.incrementAndGet();

    Set<Subscription> subs =
        (Set<Subscription>)
            ((Set<?>) getSubscriptionsForEntitySensor(event.getSource(), event.getSensor()));
    if (groovyTruth(subs)) {
      if (LOG.isTraceEnabled())
        LOG.trace(
            "sending {}, {} to {}",
            new Object[] {event.getSensor().getName(), event, join(subs, ",")});
      for (Subscription s : subs) {
        if (s.eventFilter != null && !s.eventFilter.apply(event)) continue;
        final Subscription sAtClosureCreation = s;
        em.submit(
            mapOf("tag", s.subscriberExecutionManagerTag),
            new Runnable() {
              public void run() {
                sAtClosureCreation.listener.onEvent(event);
              }
            });
        totalEventsDeliveredCount.incrementAndGet();
      }
    }
  }
 static Object makeEntitySensorToken(SensorEvent<?> se) {
   return makeEntitySensorToken(se.getSource(), se.getSensor());
 }