boolean isComplete = pipeline.getStatus().isComplete(); ExecutionStatus pipelineStatus = pipeline.getStatus(); CanaryAnalysisExecutionStatusResponse.CanaryAnalysisExecutionStatusResponseBuilder responseBuilder = CanaryAnalysisExecutionStatusResponse.builder() .application(pipeline.getApplication()) .pipelineId(pipeline.getId()) .stageStatus(pipeline.getStages() .stream() .map(stage -> new StageMetadata(stage.getType(), stage.getName(), stage.getStatus())) pipeline.getStages().stream() .filter(stage -> stage.getType().equals(SetupAndExecuteCanariesStage.STAGE_TYPE)) .findFirst() pipeline.getStages().stream() .filter(stage -> stage.getType().equals(GenerateCanaryAnalysisResultStage.STAGE_TYPE)) .findFirst() pipeline.getStages().stream() .filter(stage -> stage.getContext().containsKey("exception")) .findFirst() .ifPresent(stage -> responseBuilder.exception(stage.getContext().get("exception"))); Long buildTime = pipeline.getBuildTime(); if (buildTime != null) { responseBuilder Long startTime = pipeline.getStartTime(); if (startTime != null) {
private void handleStartupFailure(Execution execution, Throwable failure) { final String canceledBy = "system"; final String reason = "Failed on startup: " + failure.getMessage(); final ExecutionStatus status = ExecutionStatus.TERMINAL; log.error("Failed to start {} {}", execution.getType(), execution.getId(), failure); executionRepository.updateStatus(execution.getType(), execution.getId(), status); executionRepository.cancel(execution.getType(), execution.getId(), canceledBy, reason); }
@Override public boolean shouldProcessExecution(Execution execution) { return CanaryAnalysisService.CANARY_ANALYSIS_PIPELINE_NAME.equals(execution.getName()); }
public CanaryConfig getCanaryConfig(Execution pipeline) { Stage contextStage = pipeline.getStages().stream() .filter(stage -> stage.getRefId().equals(CanaryStageNames.REFID_SET_CONTEXT)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Unable to find stage '" + CanaryStageNames.REFID_SET_CONTEXT + "' in pipeline ID '" + pipeline.getId() + "'")); Map<String, Object> context = contextStage.getContext(); Map<String, Object> canaryConfigMap = (Map<String, Object>)context.get("canaryConfig"); return objectMapper.convertValue(canaryConfigMap, CanaryConfig.class); }
public Map getJudgeComparisonResults(@PathVariable String executionId) { Execution pipeline = executionRepository.retrieve(Execution.ExecutionType.PIPELINE, executionId); String canaryExecutionId = pipeline.getId(); Stage compareJudgeResultsStage = pipeline.getStages().stream() .filter(stage -> stage.getRefId().equals("compareJudgeResults")) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Unable to find stage 'compareJudgeResults' in pipeline ID '" + canaryExecutionId + "'")); Map<String, Object> compareJudgeResultsOutputs = compareJudgeResultsStage.getOutputs(); Boolean isComplete = pipeline.getStatus().isComplete(); String pipelineStatus = pipeline.getStatus().toString().toLowerCase(); ImmutableMap.Builder<String, Object> comparisonResult = ImmutableMap.builder(); List<Stage> stagesWithException = pipeline.getStages().stream() .filter(stage -> stage.getContext().containsKey("exception")) .collect(Collectors.toList());
protected Map<String, String> serializeExecution(@Nonnull Execution execution) { Map<String, String> map = new HashMap<>(); try { map.put("application", execution.getApplication()); map.put("canceled", String.valueOf(execution.isCanceled())); map.put("limitConcurrent", String.valueOf(execution.isLimitConcurrent())); map.put("buildTime", String.valueOf(execution.getBuildTime() != null ? execution.getBuildTime() : 0L)); map.put("startTime", execution.getStartTime() != null ? execution.getStartTime().toString() : null); map.put("endTime", execution.getEndTime() != null ? execution.getEndTime().toString() : null); map.put("startTimeExpiry", execution.getStartTimeExpiry() != null ? String.valueOf(execution.getStartTimeExpiry()) : null); map.put("status", execution.getStatus().name()); map.put("authentication", mapper.writeValueAsString(execution.getAuthentication())); map.put("paused", mapper.writeValueAsString(execution.getPaused())); map.put("keepWaitingPipelines", String.valueOf(execution.isKeepWaitingPipelines())); map.put("origin", execution.getOrigin()); map.put("source", mapper.writeValueAsString(execution.getSource())); map.put("trigger", mapper.writeValueAsString(execution.getTrigger())); map.put("systemNotifications", mapper.writeValueAsString(execution.getSystemNotifications())); } catch (JsonProcessingException e) { throw new ExecutionSerializationException("Failed serializing execution", e); execution.getStages().forEach(s -> map.putAll(serializeStage(s))); if (execution.getType() == PIPELINE) { try { map.put("name", execution.getName()); map.put("pipelineConfigId", execution.getPipelineConfigId()); map.put("notifications", mapper.writeValueAsString(execution.getNotifications())); map.put("initialConfig", mapper.writeValueAsString(execution.getInitialConfig())); } catch (JsonProcessingException e) {
protected Execution buildExecution(@Nonnull Execution execution, @Nonnull Map<String, String> map, List<String> stageIds) { Id serializationErrorId = registry .createId("executions.deserialization.error") .withTag("executionType", execution.getType().toString()) .withTag("application", execution.getApplication()); execution.setCanceled(Boolean.parseBoolean(map.get("canceled"))); execution.setCanceledBy(map.get("canceledBy")); execution.setCancellationReason(map.get("cancellationReason")); execution.setLimitConcurrent(Boolean.parseBoolean(map.get("limitConcurrent"))); execution.setBuildTime(NumberUtils.createLong(map.get("buildTime"))); execution.setStartTime(NumberUtils.createLong(map.get("startTime"))); if (map.get("startTimeExpiry") != null) { execution.setStartTimeExpiry(Long.valueOf(map.get("startTimeExpiry"))); execution.setEndTime(NumberUtils.createLong(map.get("endTime"))); if (map.get("status") != null) { execution.setStatus(ExecutionStatus.valueOf(map.get("status"))); execution.setAuthentication(mapper.readValue(map.get("authentication"), Execution.AuthenticationDetails.class)); if (map.get("paused") != null) { execution.setPaused(mapper.readValue(map.get("paused"), PausedDetails.class)); execution.setKeepWaitingPipelines(Boolean.parseBoolean(map.get("keepWaitingPipelines"))); execution.setOrigin(map.get("origin")); if (map.get("source") != null) { execution.setSource(mapper.readValue(map.get("source"), Execution.PipelineSource.class)); execution.setTrigger(map.get("trigger") != null ? mapper.readValue(map.get("trigger"), Trigger.class) : NO_TRIGGER); if (map.get("systemNotifications") != null) {
c.sadd(alljobsKey(execution.getType()), execution.getId()); c.sadd(appKey(execution.getType(), execution.getApplication()), execution.getId()); if (execution.getStatus() == BUFFERED) { c.sadd(allBufferedExecutionsKey(execution.getType()), execution.getId()); } else { c.srem(allBufferedExecutionsKey(execution.getType()), execution.getId()); tx.hdel(key, "config"); tx.hmset(key, filterValues(map, Objects::nonNull)); if (!execution.getStages().isEmpty()) { tx.del(indexKey); tx.rpush(indexKey, execution.getStages().stream() .map(Stage::getId) .toArray(String[]::new) }); if (execution.getTrigger().getCorrelationId() != null) { c.set( format("correlation:%s", execution.getTrigger().getCorrelationId()), execution.getId() );
value.put("executionId", execution.getId()); value.put("executionType", execution.getType().toString()); value.put("application", execution.getApplication()); if (execution.getAuthentication() != null) { value.put("user", execution.getAuthentication().getUser()); if (execution.getType() == ORCHESTRATION) { value.put("description", execution.getDescription()); } else if (execution.getType() == PIPELINE) { value.put("description", execution.getName()); value.put("pipelineConfigId", execution.getPipelineConfigId()); execution.getApplication(), account, cluster,
@Override public Object get(@Nullable Object key) { Object value = super.get(key); if (value != null) { log.warn( "Global context key \"{}\" accessed by {} {}[{}] \"{}\"", key, execution.getApplication(), execution.getType(), execution.getId(), Optional.ofNullable(execution.getName()).orElseGet(execution::getDescription) ); Id counterId = registry .createId("global.context.access") .withTag("application", execution.getApplication()) .withTag("key", String.valueOf(key)); registry .counter(counterId) .increment(); } return value; } }
private List<String> getMetricSetListIds(Execution execution, String stagePrefix) { List<Stage> stages = execution.getStages(); return stages.stream() .filter(stage -> { String refId = stage.getRefId(); return refId != null && refId.startsWith(stagePrefix); }) .map(stage -> resolveMetricSetListId(stage)) .collect(Collectors.toList()); }
@Override public void store(@Nonnull Execution execution) { RedisClientDelegate delegate = getRedisDelegate(execution); storeExecutionInternal(delegate, execution); if (execution.getType() == PIPELINE) { delegate.withCommandsClient(c -> { c.zadd(executionsByPipelineKey(execution.getPipelineConfigId()), execution.getBuildTime() != null ? execution.getBuildTime() : currentTimeMillis(), execution.getId() ); }); } }
private String startPipeline(Map config) throws Exception { String json = kayentaObjectMapper.writeValueAsString(config); log.info("Requested pipeline: {}", json); Execution pipeline = executionLauncher.start(Execution.ExecutionType.PIPELINE, json); return pipeline.getId(); } }
@Override public void afterExecution(Persister persister, Execution execution, ExecutionStatus executionStatus, boolean wasSuccessful) { if (execution.getType() != ORCHESTRATION) { // not concerned with pipelines right now (pipelines can have wait stages / manual judgments which skew execution time) return; } if (execution.getApplication() == null || execution.getStartTime() == null || execution.getEndTime() == null) { // should normally have all attributes but a guard just in case return; } Id id = registry .createId("executions.totalTime") .withTag("executionType", "orchestration") .withTag("successful", Boolean.valueOf(wasSuccessful).toString()) .withTag("application", execution.getApplication().toLowerCase()); registry.timer(id).record(execution.getEndTime() - execution.getStartTime(), TimeUnit.MILLISECONDS); } }
private Execution checkForCorrelatedExecution(Execution execution) { if (execution.getTrigger().getCorrelationId() == null) { return null; } Trigger trigger = execution.getTrigger(); try { Execution o = executionRepository.retrieveByCorrelationId( execution.getType(), trigger.getCorrelationId() ); log.info("Found pre-existing " + execution.getType() + " by correlation id (id: " + o.getId() + ", correlationId: " + trigger.getCorrelationId() + ")"); return o; } catch (ExecutionNotFoundException e) { // Swallow } return null; }
stage.getId(), stage.getExecution().getId(), canaryPipelineExecutionId, stage.getContext()); if (pipeline.getStatus().isComplete()) { log.debug("Not changing status of pipeline execution {} to CANCELED since execution is already completed: {}", canaryPipelineExecutionId, pipeline.getStatus()); return new CancellableStage.Result(stage, new HashMap<>()); } catch (Exception e) { log.error("Failed to cancel stage (stageId: {}, executionId: {}), e: {}", stage.getId(), stage.getExecution().getId(), e.getMessage(), e); stage.getId(), stage.getExecution().getId(), stage.getContext());
@Override public Boolean call(Execution execution) { if (!COMPLETED_STATUSES.contains(execution.getStatus().toString())) { return false; } long startTime = execution.getStartTime() == null ? execution.getBuildTime() : execution.getStartTime(); return startTime <= (Instant.ofEpochMilli(clock.millis()).minus(thresholdDays, ChronoUnit.DAYS).toEpochMilli()); } };
@Override public CancellableStage.Result cancel(Stage stage) { String readableStageDetails = format("(stageId: %s, executionId: %s, context: %s)", stage.getId(), stage.getExecution().getId(), stage.getContext()); log.info(format("Cancelling stage %s", readableStageDetails)); try { String executionId = (String) stage.getContext().get("executionId"); if (executionId != null) { if (executionRepository == null) { log.error(format("Stage %s could not be canceled w/o front50 enabled. Please set 'front50.enabled: true' in your orca config.", readableStageDetails)); } else { Execution childPipeline = executionRepository.retrieve(PIPELINE, executionId); if (!childPipeline.isCanceled()) { // flag the child pipeline as canceled (actual cancellation will happen asynchronously) executionRepository.cancel(stage.getExecution().getType(), executionId, "parent pipeline", null); } } } } catch (Exception e) { log.error(format("Failed to cancel stage %s, e: %s", readableStageDetails, e.getMessage()), e); } return new CancellableStage.Result(stage, emptyMap()); } }
@ApiOperation(value = "Cancel a pipeline execution") @RequestMapping(value = "/{executionId}/cancel", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.ACCEPTED) void cancel(@PathVariable String executionId) { log.info("Cancelling pipeline execution {}...", executionId); Execution pipeline = executionRepository.retrieve(Execution.ExecutionType.PIPELINE, executionId); if (pipeline.getStatus().isComplete()) { log.debug("Not changing status of pipeline execution {} to CANCELED since execution is already completed: {}", executionId, pipeline.getStatus()); return; } executionRepository.cancel(Execution.ExecutionType.PIPELINE, executionId); executionRepository.updateStatus(Execution.ExecutionType.PIPELINE, executionId, ExecutionStatus.CANCELED); }
@Override public int compare(Execution a, Execution b) { Long aBuildTime = Optional.ofNullable(a.getBuildTime()).orElse(0L); Long bBuildTime = Optional.ofNullable(b.getBuildTime()).orElse(0L); int buildCompare = aBuildTime.compareTo(bBuildTime); if (buildCompare == 0) { return a.getId().compareTo(b.getId()); } return buildCompare; } };