Skip to content

Instantly share code, notes, and snippets.

@fieldju
Created July 24, 2019 23:20
Show Gist options
  • Save fieldju/ff54a7b9615696d89336b7f952f2ac1d to your computer and use it in GitHub Desktop.
Save fieldju/ff54a7b9615696d89336b7f952f2ac1d to your computer and use it in GitHub Desktop.
package com.nike.kayenta.events;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.netflix.kayenta.canaryanalysis.domain.CanaryAnalysisExecutionStatusResponse;
import com.netflix.kayenta.canaryanalysis.event.StandaloneCanaryAnalysisExecutionCompletedEvent;
import com.nike.kayenta.model.EventType;
import com.nike.kayenta.model.NikeKayentaConfig;
import com.nike.kayenta.model.NotificationChannel;
import com.nike.kayenta.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.util.*;
/**
* Standalone canary analysis pipeline execution (SCAPE) completed event listener.
*
* Event hook for adding custom Nike logic when a SCAPE has finished.
* This will allow us to asynchronously generate html reports, process notifications and track usage KPIs.
*/
@Slf4j
@Component
public class ScapeCompletedEventListener implements ApplicationListener<StandaloneCanaryAnalysisExecutionCompletedEvent> {
private final ObjectMapper kayentaObjectMapper;
private final HtmlReportService htmlReportService;
private final KpiService kpiService;
private final List<NotificationService> notificationServices;
@Autowired
public ScapeCompletedEventListener(ObjectMapper kayentaObjectMapper,
HtmlReportService htmlReportService,
NotificationService emailNotificationService,
NotificationService httpNotificationService,
NotificationService slackNotificationService,
NotificationService smsNotificationService,
KpiService kpiService) {
this.kayentaObjectMapper = kayentaObjectMapper;
this.htmlReportService = htmlReportService;
this.kpiService = kpiService;
// TODO do fancy spring way
notificationServices = ImmutableList.of(
slackNotificationService,
emailNotificationService,
httpNotificationService,
smsNotificationService
);
}
@Override
public void onApplicationEvent(StandaloneCanaryAnalysisExecutionCompletedEvent event) {
CanaryAnalysisExecutionStatusResponse executionStatusResponse = event.getCanaryAnalysisExecutionStatusResponse();
log.info("Processing SCAPE Complete event for execution id: {}", executionStatusResponse.getPipelineId());
Map<String, Object> siteLocal = Optional.ofNullable(executionStatusResponse.getCanaryAnalysisExecutionRequest()
.getSiteLocal()).orElse(Collections.emptyMap());
// Generate and upload human readable http report to Report Archiver S3 bucket.
log.info("Generating and uploading html report for execution id: {}", executionStatusResponse.getPipelineId());
String htmlReportUrl = htmlReportService.getUrl(executionStatusResponse);
htmlReportService.createAndUploadReport(executionStatusResponse);
log.info("SCAPE Report at '{}' for execution id: {}", htmlReportUrl, executionStatusResponse.getPipelineId());
log.info("Processing notifications for execution id: {}", executionStatusResponse.getPipelineId());
NikeKayentaConfig nikeKayentaConfig = kayentaObjectMapper.convertValue(siteLocal, NikeKayentaConfig.class);
processNotifications(nikeKayentaConfig, htmlReportUrl, executionStatusResponse);
log.info("Processing KPIs for execution id: {}", executionStatusResponse.getPipelineId());
// Generate KPI Metrics
kpiService.trackScapeComplete(nikeKayentaConfig, executionStatusResponse);
log.info("Finished processing complete event for execution id: {}", executionStatusResponse.getPipelineId());
}
private void processNotifications(NikeKayentaConfig nikeKayentaConfig,
String htmlReportUrl,
CanaryAnalysisExecutionStatusResponse executionStatusResponse) {
EventType event = executionStatusResponse.getCanaryAnalysisExecutionResult().isDidPassThresholds() ?
EventType.SUCCESS : EventType.FAILURE;
List<NotificationChannel> channels = nikeKayentaConfig.getNotificationChannels();
channels.stream()
.filter(notificationChannel -> notificationChannel.getOn().contains(event))
.forEach(notificationChannel -> notificationServices.stream()
.filter(it -> it.handlesType() == notificationChannel.getType())
.forEach(notificationService -> notificationService
.notifySCAPEComplete(nikeKayentaConfig, notificationChannel, executionStatusResponse, htmlReportUrl)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment