@Override
 public void onSuccess(AbstractMonitorEvent[] auditEvents) {
   synchronized (PaaSProviderPollingMonitor.this) {
     if (log.isTraceEnabled()) {
       log.trace("Polled from date {}", lastPollingDate);
     }
     if (log.isDebugEnabled() && auditEvents != null && auditEvents.length > 0) {
       log.debug("Saving events for cloud {}", cloudId);
       for (AbstractMonitorEvent event : auditEvents) {
         log.debug(event.toString());
       }
     }
     if (auditEvents != null && auditEvents.length > 0) {
       for (AbstractMonitorEvent event : auditEvents) {
         // Enrich event with cloud id before saving them
         event.setCloudId(cloudId);
       }
       for (IPaasEventListener listener : listeners) {
         for (AbstractMonitorEvent event : auditEvents) {
           if (listener.canHandle(event)) {
             listener.eventHappened(event);
           }
           if (event.getDate() > 0) {
             Date eventDate = new Date(event.getDate());
             lastPollingDate = eventDate.after(lastPollingDate) ? eventDate : lastPollingDate;
           } else {
             event.setDate(System.currentTimeMillis());
           }
         }
       }
       monitorDAO.save(auditEvents);
     }
     getEventsInProgress = false;
   }
 }
  /**
   * Create a new instance of the {@link PaaSProviderPollingMonitor} to monitor the given paas
   * provider.
   *
   * @param paaSProvider The paas provider to monitor.
   */
  @SuppressWarnings("rawtypes")
  public PaaSProviderPollingMonitor(
      IGenericSearchDAO dao,
      IGenericSearchDAO monitorDAO,
      IPaaSProvider paaSProvider,
      List<IPaasEventListener> listeners,
      String cloudId) {
    this.cloudId = cloudId;
    this.dao = dao;
    this.monitorDAO = monitorDAO;
    this.paaSProvider = paaSProvider;
    this.listeners = listeners;
    Set<Class<?>> eventClasses = Sets.newHashSet();
    try {
      eventClasses = TypeScanner.scanTypes("alien4cloud.paas.model", AbstractMonitorEvent.class);
    } catch (ClassNotFoundException e) {
      log.info("No event class derived from {} found", AbstractMonitorEvent.class.getName());
    }
    Map<String, String[]> filter = Maps.newHashMap();
    filter.put("cloudId", new String[] {this.cloudId});
    // sort by filed date DESC
    SearchQueryHelperBuilder searchQueryHelperBuilder =
        monitorDAO
            .getQueryHelper()
            .buildSearchQuery("deploymentmonitorevents")
            .types(eventClasses.toArray(new Class<?>[eventClasses.size()]))
            .filters(filter)
            .fieldSort("date", true);

    // the first one is the one with the latest date
    GetMultipleDataResult lastestEventResult = monitorDAO.search(searchQueryHelperBuilder, 0, 1);
    if (lastestEventResult.getData().length > 0) {
      AbstractMonitorEvent lastEvent = (AbstractMonitorEvent) lastestEventResult.getData()[0];
      Date lastEventDate = new Date(lastEvent.getDate());
      log.info(
          "Recovering events from the last in elasticsearch {} of type {}",
          lastEventDate,
          lastEvent.getClass().getName());
      this.lastPollingDate = lastEventDate;
    } else {
      this.lastPollingDate = new Date();
      log.debug(
          "No monitor events found, the last polling date will be current date {}",
          this.lastPollingDate);
    }
    paaSEventsCallback = new PaaSEventsCallback();
  }
 private AbstractMonitorEvent toAlienEvent(Event cloudifyEvent) {
   AbstractMonitorEvent alienEvent;
   switch (cloudifyEvent.getEventType()) {
     case EventType.WORKFLOW_SUCCEEDED:
       PaaSDeploymentStatusMonitorEvent succeededStatusEvent =
           new PaaSDeploymentStatusMonitorEvent();
       if (Workflow.INSTALL.equals(cloudifyEvent.getContext().getWorkflowId())) {
         succeededStatusEvent.setDeploymentStatus(DeploymentStatus.DEPLOYED);
       } else if (Workflow.DELETE_DEPLOYMENT_ENVIRONMENT.equals(
           cloudifyEvent.getContext().getWorkflowId())) {
         succeededStatusEvent.setDeploymentStatus(DeploymentStatus.UNDEPLOYED);
       } else {
         return null;
       }
       alienEvent = succeededStatusEvent;
       break;
     case EventType.WORKFLOW_FAILED:
       PaaSDeploymentStatusMonitorEvent failedStatusEvent = new PaaSDeploymentStatusMonitorEvent();
       failedStatusEvent.setDeploymentStatus(DeploymentStatus.FAILURE);
       alienEvent = failedStatusEvent;
       break;
     case EventType.TASK_SUCCEEDED:
       if (Workflow.DELETE_DEPLOYMENT_ENVIRONMENT.equals(
               cloudifyEvent.getContext().getWorkflowId())
           && "riemann_controller.tasks.delete".equals(cloudifyEvent.getContext().getTaskName())) {
         PaaSDeploymentStatusMonitorEvent undeployedEvent = new PaaSDeploymentStatusMonitorEvent();
         undeployedEvent.setDeploymentStatus(DeploymentStatus.UNDEPLOYED);
         alienEvent = undeployedEvent;
       } else {
         String newInstanceState =
             CloudifyLifeCycle.getSucceededInstanceState(
                 cloudifyEvent.getContext().getOperation());
         if (newInstanceState == null) {
           return null;
         }
         PaaSInstanceStateMonitorEvent instanceTaskStartedEvent =
             new PaaSInstanceStateMonitorEvent();
         instanceTaskStartedEvent.setInstanceId(cloudifyEvent.getContext().getNodeId());
         instanceTaskStartedEvent.setNodeTemplateId(cloudifyEvent.getContext().getNodeName());
         instanceTaskStartedEvent.setInstanceState(newInstanceState);
         instanceTaskStartedEvent.setInstanceStatus(
             statusService.getInstanceStatusFromState(newInstanceState));
         alienEvent = instanceTaskStartedEvent;
       }
       break;
     case EventType.A4C_PERSISTENT_EVENT:
       String persistentCloudifyEvent = cloudifyEvent.getMessage().getText();
       ObjectMapper objectMapper = new ObjectMapper();
       objectMapper.setPropertyNamingStrategy(
           PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
       try {
         EventAlienPersistent eventAlienPersistent =
             objectMapper.readValue(persistentCloudifyEvent, EventAlienPersistent.class);
         // query API
         // TODO make that Async
         NodeInstance instance = nodeInstanceClient.read(cloudifyEvent.getContext().getNodeId());
         String attributeValue =
             (String)
                 instance
                     .getRuntimeProperties()
                     .get(eventAlienPersistent.getPersistentResourceId());
         alienEvent =
             new PaaSInstancePersistentResourceMonitorEvent(
                 cloudifyEvent.getContext().getNodeName(),
                 cloudifyEvent.getContext().getNodeId(),
                 eventAlienPersistent.getPersistentAlienAttribute(),
                 attributeValue);
       } catch (IOException e) {
         return null;
       }
       break;
     case EventType.A4C_WORKFLOW_STARTED:
       String wfCloudifyEvent = cloudifyEvent.getMessage().getText();
       objectMapper = new ObjectMapper();
       objectMapper.setPropertyNamingStrategy(
           PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
       try {
         EventAlienWorkflowStarted eventAlienWorkflowStarted =
             objectMapper.readValue(wfCloudifyEvent, EventAlienWorkflowStarted.class);
         PaaSWorkflowStepMonitorEvent e = new PaaSWorkflowStepMonitorEvent();
         PaaSWorkflowMonitorEvent pwme = new PaaSWorkflowMonitorEvent();
         pwme.setExecutionId(cloudifyEvent.getContext().getExecutionId());
         pwme.setWorkflowId(eventAlienWorkflowStarted.getWorkflowName());
         pwme.setSubworkflow(eventAlienWorkflowStarted.getSubworkflow());
         alienEvent = pwme;
       } catch (IOException e) {
         return null;
       }
       break;
     case EventType.A4C_WORKFLOW_EVENT:
       wfCloudifyEvent = cloudifyEvent.getMessage().getText();
       objectMapper = new ObjectMapper();
       objectMapper.setPropertyNamingStrategy(
           PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
       try {
         EventAlienWorkflow eventAlienPersistent =
             objectMapper.readValue(wfCloudifyEvent, EventAlienWorkflow.class);
         PaaSWorkflowStepMonitorEvent e = new PaaSWorkflowStepMonitorEvent();
         e.setNodeId(cloudifyEvent.getContext().getNodeName());
         e.setInstanceId(cloudifyEvent.getContext().getNodeId());
         e.setStepId(eventAlienPersistent.getStepId());
         e.setStage(eventAlienPersistent.getStage());
         String workflowId = cloudifyEvent.getContext().getWorkflowId();
         e.setExecutionId(cloudifyEvent.getContext().getExecutionId());
         if (workflowId.startsWith(Workflow.A4C_PREFIX)) {
           workflowId = workflowId.substring(Workflow.A4C_PREFIX.length());
         }
         e.setWorkflowId(cloudifyEvent.getContext().getWorkflowId());
         alienEvent = e;
       } catch (IOException e) {
         return null;
       }
       break;
     default:
       return null;
   }
   alienEvent.setDate(
       DatatypeConverter.parseDateTime(cloudifyEvent.getTimestamp()).getTimeInMillis());
   String alienDeploymentId =
       paaSDeploymentIdToAlienDeploymentIdMapping.get(
           cloudifyEvent.getContext().getDeploymentId());
   if (alienDeploymentId == null) {
     if (log.isDebugEnabled()) {
       log.debug(
           "Alien deployment id is not found for paaS deployment {}, must ignore this event {}",
           cloudifyEvent.getContext().getDeploymentId(),
           cloudifyEvent);
     }
     return null;
   }
   alienEvent.setDeploymentId(alienDeploymentId);
   return alienEvent;
 }