Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OP-20731: BugFix to implement validation for verification stage in isd #216

Merged
merged 3 commits into from
Nov 8, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ public class VerificationTriggerTask implements Task {

private static final String PAYLOAD_CONSTRAINT = "payloadConstraint";

private static final String LOG_TEMPLATE = "logTemplate";
private static final String METRIC_TEMPLATE = "metricTemplate";
private static final String CANARYRESULTSCORE = "canaryresultscore";
private static final String LIFETIME = "lifetime";
private static final String MINICANARYRESULT = "minicanaryresult";
private static final String BASELINESTARTTIME = "baselinestarttime";
private static final String CANARYSTARTTIME = "canarystarttime";

private final Logger logger = LoggerFactory.getLogger(getClass());

@Autowired
Expand Down Expand Up @@ -96,6 +104,12 @@ private TaskResult triggerAnalysis(StageExecution stage) throws UnsupportedEncod
Map<String, Object> contextMap = new HashMap<>();
Map<String, Object> outputs = new HashMap<>();
long startTime = Instant.now().toEpochMilli();
GateModel gateModel = new GateModel();
String stringParam = gson.toJson(stage.getContext().get("parameters"), Map.class);
logger.debug("Verification GATE parameters : {}", stringParam);
JsonObject parameters = gson.fromJson(stringParam, JsonObject.class);
verifyStageParams(parameters, gateModel);

String triggerUrl = getTriggerURL(stage, outputs);
if (triggerUrl == null) {
return TaskResult.builder(ExecutionStatus.TERMINAL)
Expand Down Expand Up @@ -180,6 +194,23 @@ private TaskResult triggerAnalysis(StageExecution stage, Map<String, Object> out
}
}

private static void verifyStageParams(JsonObject parameters, GateModel gateModel) throws IllegalArgumentException {
if (!parameters.has(LOG_TEMPLATE)) {
throw new IllegalArgumentException("Verification gate requires a Log Template to be configured");
}
if (!parameters.has(METRIC_TEMPLATE)) {
throw new IllegalArgumentException("Verification gate requires a Metric Template to be configured");
}
if (!parameters.has(CANARYRESULTSCORE) || parameters.get(CANARYRESULTSCORE).getAsString().isEmpty() || parameters.get(CANARYRESULTSCORE) == null ||
!parameters.has(LIFETIME) || parameters.get(LIFETIME).getAsString().isEmpty() || parameters.get(LIFETIME) == null ||
!parameters.has(MINICANARYRESULT) || parameters.get(MINICANARYRESULT).getAsString().isEmpty() || parameters.get(MINICANARYRESULT) == null) {
throw new IllegalArgumentException("Verification gate in ISD, mandatory fields are missing. Please recheck the stage");
}
if (!parameters.has(BASELINESTARTTIME) || !parameters.has(CANARYSTARTTIME)) {
throw new IllegalArgumentException("Verification gate in ISD requires baseline and canary start time for analysis");
}
}

private String getTriggerURL(StageExecution stage, Map<String, Object> outputs) throws UnsupportedEncodingException {

String triggerEndpoint = constructGateEnpoint(stage);
Expand Down Expand Up @@ -271,22 +302,22 @@ private String getPayloadString(StageExecution stage, Long startTime) throws Jso
finalJson.set(PAYLOAD_CONSTRAINT, payloadConstraintNode);

ObjectNode canaryConfig = objectMapper.createObjectNode();
canaryConfig.put("lifetimeMinutes", parameterContext.get("lifetime") != null ? (String) parameterContext.get("lifetime") : "6");
canaryConfig.put("lifetimeMinutes", parameterContext.get(LIFETIME) != null ? (String) parameterContext.get(LIFETIME) : "6");
canaryConfig.set("canaryHealthCheckHandler", objectMapper.createObjectNode()
.put(MINIMUM_CANARY_RESULT_SCORE, parameterContext.get("minicanaryresult") != null ? (String) parameterContext.get("minicanaryresult") : "70" ));
.put(MINIMUM_CANARY_RESULT_SCORE, parameterContext.get(MINICANARYRESULT) != null ? (String) parameterContext.get(MINICANARYRESULT) : "70" ));
canaryConfig.set("canarySuccessCriteria", objectMapper.createObjectNode()
.put("canaryResultScore", parameterContext.get("canaryresultscore") != null ? (String) parameterContext.get("canaryresultscore") : "90"));
.put("canaryResultScore", parameterContext.get(CANARYRESULTSCORE) != null ? (String) parameterContext.get(CANARYRESULTSCORE) : "90"));
canaryConfig.put("name", stage.getExecution().getAuthentication().getUser());

ObjectNode baselinePayload = objectMapper.createObjectNode();
ObjectNode canaryPayload = objectMapper.createObjectNode();
if (parameterContext.get("logTemplate") != null && ! ((String) parameterContext.get("logTemplate")).isEmpty()) {
if (parameterContext.get(LOG_TEMPLATE) != null && ! ((String) parameterContext.get(LOG_TEMPLATE)).isEmpty()) {
baselinePayload.set(LOG,
prepareJson(stage.getName(), stage.getExecution().getName()));
canaryPayload.set(LOG,
prepareJson(stage.getName(), stage.getExecution().getName()));
}
if (parameterContext.get("metricTemplate") != null && !((String) parameterContext.get("metricTemplate")).isEmpty()) {
if (parameterContext.get(METRIC_TEMPLATE) != null && !((String) parameterContext.get(METRIC_TEMPLATE)).isEmpty()) {
baselinePayload.set(METRIC,
prepareJson(stage.getName(), stage.getExecution().getName()));
canaryPayload.set(METRIC,
Expand All @@ -304,9 +335,9 @@ private String getPayloadString(StageExecution stage, Long startTime) throws Jso
} else {
Long baselinestarttime = null;
try{
baselinestarttime = parameterContext.get("baselinestarttime") != null ? (Long) parameterContext.get("baselinestarttime") : startTime;
baselinestarttime = parameterContext.get(BASELINESTARTTIME) != null ? (Long) parameterContext.get(BASELINESTARTTIME) : startTime;
} catch(ClassCastException cce){
baselinestarttime = parameterContext.get("baselinestarttime") != null ? Double.valueOf( (Double) parameterContext.get("baselinestarttime")).longValue() : startTime;
baselinestarttime = parameterContext.get(BASELINESTARTTIME) != null ? Double.valueOf( (Double) parameterContext.get(BASELINESTARTTIME)).longValue() : startTime;
}
triggerPayload.put("baselineStartTimeMs",
baselinestarttime);
Expand All @@ -317,9 +348,9 @@ private String getPayloadString(StageExecution stage, Long startTime) throws Jso
} else {
Long canarystarttime = null;
try {
canarystarttime = parameterContext.get("canarystarttime") != null ? (Long) parameterContext.get("canarystarttime") : startTime;
canarystarttime = parameterContext.get(CANARYSTARTTIME) != null ? (Long) parameterContext.get(CANARYSTARTTIME) : startTime;
} catch (ClassCastException cce){
canarystarttime = parameterContext.get("canarystarttime") != null ? Double.valueOf((Double) parameterContext.get("canarystarttime")).longValue() : startTime;
canarystarttime = parameterContext.get(CANARYSTARTTIME) != null ? Double.valueOf((Double) parameterContext.get(CANARYSTARTTIME)).longValue() : startTime;
}
triggerPayload.put("canaryStartTimeMs",
canarystarttime);
Expand Down Expand Up @@ -400,18 +431,10 @@ private void createVerificationGate(StageExecution stage, ApplicationModel appli
gateModel.setRefId(stage.getRefId());
gateModel.setPipelineId(applicationModel.getPipelineId());

verifyStageParams(parameters, gateModel);
//Verification Gate specific details start
if (parameters.has("logTemplate")) {
gateModel.setLogTemplateName(parameters.get("logTemplate").getAsString().trim());
}else {
throw new IllegalArgumentException("Verification gate requires a Log Template to be configured");
}

if (parameters.has("metricTemplate")) {
gateModel.setMetricTemplateName(parameters.get("metricTemplate").getAsString().trim());
}else {
throw new IllegalArgumentException("Verification gate requires a Metric Template to be configured");
}
gateModel.setLogTemplateName(parameters.get("logTemplate").getAsString().trim());
gateModel.setMetricTemplateName(parameters.get("metricTemplate").getAsString().trim());
//Verification Gate specific details end

gateModel.setEnvironmentId(getEnvironmentId(parameters));
Expand Down