From 3b85dd95e487cc71399ab2bc772ecca07362a338 Mon Sep 17 00:00:00 2001 From: Angelo Rodriguez Date: Mon, 11 May 2020 11:30:33 -0400 Subject: [PATCH] OOE-19 Update Bamboo Plugin with Show All Errors and Removing Increasing Gate --- .../com/overops/plugins/bamboo/TaskType.java | 30 +- .../plugins/bamboo/configuration/Const.java | 13 +- .../configuration/TaskConfiguration.java | 31 +- .../bamboo/model/OOReportRegressedEvent.java | 32 -- .../bamboo/model/OverOpsReportModel.java | 284 ----------- .../plugins/bamboo/model/QueryOverOps.java | 231 --------- .../bamboo/model/ReportEventModel.java | 96 ---- .../bamboo/model/ReportRegressedModel.java | 31 -- .../bamboo/service/OverOpsService.java | 13 - .../service/impl/OverOpsServiceImpl.java | 218 --------- .../bamboo/service/impl/ReportBuilder.java | 452 ------------------ .../plugins/bamboo/utils/ReportUtils.java | 215 --------- .../overops/plugins/bamboo/overops.properties | 11 +- .../resources/templates/editTaskConfig.ftl | 19 +- 14 files changed, 25 insertions(+), 1651 deletions(-) delete mode 100644 src/main/java/com/overops/plugins/bamboo/model/OOReportRegressedEvent.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/model/OverOpsReportModel.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/model/QueryOverOps.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/model/ReportEventModel.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/model/ReportRegressedModel.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/service/OverOpsService.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/service/impl/OverOpsServiceImpl.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/service/impl/ReportBuilder.java delete mode 100644 src/main/java/com/overops/plugins/bamboo/utils/ReportUtils.java diff --git a/src/main/java/com/overops/plugins/bamboo/TaskType.java b/src/main/java/com/overops/plugins/bamboo/TaskType.java index ecf7a40..a77021b 100644 --- a/src/main/java/com/overops/plugins/bamboo/TaskType.java +++ b/src/main/java/com/overops/plugins/bamboo/TaskType.java @@ -73,15 +73,19 @@ public TaskResult execute(@NotNull TaskContext context) throws TaskException { try { logger.addBuildLogEntry("[" + Utils.getArtifactId() + " v" + Utils.getVersion() + "]"); + boolean showAllEvents = Boolean.parseBoolean(context.getConfigurationMap().get(Const.SHOW_ALL_EVENTS)); boolean isDebug = Boolean.parseBoolean(context.getConfigurationMap().get(Const.DEBUG)); PrintStream printStream = isDebug ? new BambooPrintWriter(System.out, logger) : null; QualityReport reportModel = overOpsService.runQualityReport(endPoint, apiKey, query, Requestor.BAMBOO, printStream, isDebug); - context.getBuildContext().getBuildResult().getCustomBuildData().put("overOpsReport", objectMapper.writeValueAsString(reportModel.getHtmlParts())); + context.getBuildContext().getBuildResult().getCustomBuildData().put("overOpsReport", objectMapper.writeValueAsString(reportModel.getHtmlParts(showAllEvents))); context.getBuildContext().getBuildResult().getCustomBuildData().put("isOverOpsStep", "true"); if (reportModel.getStatusCode() == ReportStatus.FAILED) { + if ((reportModel.getExceptionDetails() != null) && Boolean.parseBoolean(context.getConfigurationMap().get(Const.PASS_BUILD_ON_QR_EXCEPTION))) { + return resultBuilder.success().build(); + } return resultBuilder.failed().build(); } else { return resultBuilder.success().build(); @@ -132,23 +136,13 @@ private QualityReportParams getQualityReportParams(ConfigurationMap params) { qrp.setCriticalExceptionTypes(""); } - if (Boolean.parseBoolean(params.get(Const.CHECK_INCREASING_ERRORS))) { - qrp.setActiveTimespan(params.get(Const.ACTIVE_TIMESPAN)); - qrp.setBaselineTimespan(params.get(Const.BASELINE_TIMESPAN)); - qrp.setMinVolumeThreshold(NumberUtils.toInt(params.get(Const.MIN_VOLUME_THRESHOLD), 0)); - qrp.setMinErrorRateThreshold(NumberUtils.toDouble(params.get(Const.MIN_RATE_THRESHOLD), 0)); - qrp.setRegressionDelta(NumberUtils.toDouble(params.get(Const.REGRESSION_DELTA), 0)); - qrp.setCriticalRegressionDelta(NumberUtils.toDouble(params.get(Const.CRITICAL_REGRESSION_THRESHOLD), 0)); - qrp.setApplySeasonality(Boolean.parseBoolean(params.get(Const.APPLY_SEASONALITY))); - } else { - qrp.setActiveTimespan("0"); - qrp.setBaselineTimespan("0"); - qrp.setMinVolumeThreshold(0); - qrp.setMinErrorRateThreshold(0); - qrp.setRegressionDelta(0); - qrp.setCriticalRegressionDelta(0); - qrp.setApplySeasonality(false); - } + qrp.setActiveTimespan("0"); + qrp.setBaselineTimespan("0"); + qrp.setMinVolumeThreshold(0); + qrp.setMinErrorRateThreshold(0); + qrp.setRegressionDelta(0); + qrp.setCriticalRegressionDelta(0); + qrp.setApplySeasonality(false); qrp.setDebug(Boolean.parseBoolean(params.get(Const.DEBUG))); return qrp; diff --git a/src/main/java/com/overops/plugins/bamboo/configuration/Const.java b/src/main/java/com/overops/plugins/bamboo/configuration/Const.java index a1a3f4d..1912137 100644 --- a/src/main/java/com/overops/plugins/bamboo/configuration/Const.java +++ b/src/main/java/com/overops/plugins/bamboo/configuration/Const.java @@ -21,6 +21,9 @@ public class Const { public static final String REGEX_FILTER = "regexFilter"; public static final String TOP_ERROR_COUNT = "topErrorCount"; public static final String MARK_UNSTABLE = "markUnstable"; + public static final String SHOW_ALL_EVENTS = "showAllEvents"; + public static final String PASS_BUILD_ON_QR_EXCEPTION = "passOnQRException"; + public static final String CHECK_NEW_ERRORS = "checkNewErrors"; public static final String CHECK_RESURFACED_ERRORS = "checkResurfacedErrors"; @@ -34,18 +37,8 @@ public class Const { public static final String CHECK_CRITICAL_ERRORS = "checkCriticalErrors"; public static final String CRITICAL_EXCEPTION_TYPES = "criticalExceptionTypes"; - public static final String CHECK_INCREASING_ERRORS = "checkIncreasingErrors"; - public static final String ACTIVE_TIMESPAN = "activeTimespan"; - public static final String BASELINE_TIMESPAN = "baselineTimespan"; - public static final String MIN_VOLUME_THRESHOLD = "minVolumeThreshold"; - public static final String MIN_RATE_THRESHOLD = "minRateThreshold"; - public static final String REGRESSION_DELTA = "regressionDelta"; - public static final String CRITICAL_REGRESSION_THRESHOLD = "criticalRegressionThreshold"; - public static final String APPLY_SEASONALITY = "applySeasonality"; - public static final String DEBUG = "debug"; - // default values public static final String DEFAULT_API_URL = "https://api.overops.com/"; diff --git a/src/main/java/com/overops/plugins/bamboo/configuration/TaskConfiguration.java b/src/main/java/com/overops/plugins/bamboo/configuration/TaskConfiguration.java index b2a488f..2d6e04c 100644 --- a/src/main/java/com/overops/plugins/bamboo/configuration/TaskConfiguration.java +++ b/src/main/java/com/overops/plugins/bamboo/configuration/TaskConfiguration.java @@ -44,6 +44,8 @@ public void populateContextForEdit(Map context, TaskDefinition t context.put(Const.REGEX_FILTER, config.get(Const.REGEX_FILTER)); context.put(Const.TOP_ERROR_COUNT, config.get(Const.TOP_ERROR_COUNT)); context.put(Const.MARK_UNSTABLE, config.get(Const.MARK_UNSTABLE)); + context.put(Const.SHOW_ALL_EVENTS, config.get(Const.SHOW_ALL_EVENTS)); + context.put(Const.PASS_BUILD_ON_QR_EXCEPTION, config.get(Const.PASS_BUILD_ON_QR_EXCEPTION)); // new and resurfaced quality gates context.put(Const.CHECK_NEW_ERRORS, config.get(Const.CHECK_NEW_ERRORS)); @@ -61,16 +63,6 @@ public void populateContextForEdit(Map context, TaskDefinition t context.put(Const.CHECK_CRITICAL_ERRORS, config.get(Const.CHECK_CRITICAL_ERRORS)); context.put(Const.CRITICAL_EXCEPTION_TYPES, config.get(Const.CRITICAL_EXCEPTION_TYPES)); - // increasing errors quality gate - context.put(Const.CHECK_INCREASING_ERRORS, config.get(Const.CHECK_INCREASING_ERRORS)); - context.put(Const.ACTIVE_TIMESPAN, config.get(Const.ACTIVE_TIMESPAN)); - context.put(Const.BASELINE_TIMESPAN, config.get(Const.BASELINE_TIMESPAN)); - context.put(Const.MIN_VOLUME_THRESHOLD, config.get(Const.MIN_VOLUME_THRESHOLD)); - context.put(Const.MIN_RATE_THRESHOLD, config.get(Const.MIN_RATE_THRESHOLD)); - context.put(Const.REGRESSION_DELTA, config.get(Const.REGRESSION_DELTA)); - context.put(Const.CRITICAL_REGRESSION_THRESHOLD, config.get(Const.CRITICAL_REGRESSION_THRESHOLD)); - context.put(Const.APPLY_SEASONALITY, config.get(Const.APPLY_SEASONALITY)); - // advanced settings context.put(Const.DEBUG, config.get(Const.DEBUG)); } @@ -90,6 +82,8 @@ public Map generateTaskConfigMap(ActionParametersMap params, Tas config.put(Const.REGEX_FILTER, params.getString(Const.REGEX_FILTER)); config.put(Const.TOP_ERROR_COUNT, params.getString(Const.TOP_ERROR_COUNT)); config.put(Const.MARK_UNSTABLE, params.getString(Const.MARK_UNSTABLE)); + config.put(Const.SHOW_ALL_EVENTS, params.getString(Const.SHOW_ALL_EVENTS)); + config.put(Const.PASS_BUILD_ON_QR_EXCEPTION, params.getString(Const.PASS_BUILD_ON_QR_EXCEPTION)); // new and resurfaced quality gates config.put(Const.CHECK_NEW_ERRORS, params.getString(Const.CHECK_NEW_ERRORS)); @@ -107,16 +101,6 @@ public Map generateTaskConfigMap(ActionParametersMap params, Tas config.put(Const.CHECK_CRITICAL_ERRORS, params.getString(Const.CHECK_CRITICAL_ERRORS)); config.put(Const.CRITICAL_EXCEPTION_TYPES, params.getString(Const.CRITICAL_EXCEPTION_TYPES)); - // increasing errors quality gate - config.put(Const.CHECK_INCREASING_ERRORS, params.getString(Const.CHECK_INCREASING_ERRORS)); - config.put(Const.ACTIVE_TIMESPAN, params.getString(Const.ACTIVE_TIMESPAN).toLowerCase()); // D,H,M -> d,h,m - config.put(Const.BASELINE_TIMESPAN, params.getString(Const.BASELINE_TIMESPAN).toLowerCase()); - config.put(Const.MIN_VOLUME_THRESHOLD, params.getString(Const.MIN_VOLUME_THRESHOLD)); - config.put(Const.MIN_RATE_THRESHOLD, params.getString(Const.MIN_RATE_THRESHOLD)); - config.put(Const.REGRESSION_DELTA, params.getString(Const.REGRESSION_DELTA)); - config.put(Const.CRITICAL_REGRESSION_THRESHOLD, params.getString(Const.CRITICAL_REGRESSION_THRESHOLD)); - config.put(Const.APPLY_SEASONALITY, params.getString(Const.APPLY_SEASONALITY)); - // advanced settings config.put(Const.DEBUG, params.getString(Const.DEBUG)); @@ -144,13 +128,6 @@ public void validate(ActionParametersMap params, ErrorCollection errorCollection // validate critical errors validString(Const.CRITICAL_EXCEPTION_TYPES, Const.CHECK_CRITICAL_ERRORS); - // validate increasing errors - validTimeWindow(Const.ACTIVE_TIMESPAN, Const.CHECK_INCREASING_ERRORS); - validTimeWindow(Const.BASELINE_TIMESPAN, Const.CHECK_INCREASING_ERRORS); - validNumber(Const.MIN_VOLUME_THRESHOLD, Const.CHECK_INCREASING_ERRORS); - validRange(Const.MIN_RATE_THRESHOLD, Const.CHECK_INCREASING_ERRORS); - validRange(Const.REGRESSION_DELTA, Const.CHECK_INCREASING_ERRORS); - validRange(Const.CRITICAL_REGRESSION_THRESHOLD, Const.CHECK_INCREASING_ERRORS); } // must be a number diff --git a/src/main/java/com/overops/plugins/bamboo/model/OOReportRegressedEvent.java b/src/main/java/com/overops/plugins/bamboo/model/OOReportRegressedEvent.java deleted file mode 100644 index baec6d8..0000000 --- a/src/main/java/com/overops/plugins/bamboo/model/OOReportRegressedEvent.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.overops.plugins.bamboo.model; - -import com.takipi.api.client.result.event.EventResult; -import com.takipi.api.client.util.cicd.OOReportEvent; -import com.takipi.api.client.util.regression.RegressionStringUtil; - -public class OOReportRegressedEvent extends OOReportEvent{ - - private final long baselineHits; - private final long baselineInvocations; - - public OOReportRegressedEvent(EventResult activeEvent, long baselineHits, long baselineInvocations, String type, String arcLink) { - - super(activeEvent, type, arcLink); - - this.baselineHits = baselineHits; - this.baselineInvocations = baselineInvocations; - } - - @Override - public String getEventRate() { - return RegressionStringUtil.getRegressedEventRate(getEvent(), baselineHits, baselineInvocations); - } - - public long getBaselineHits() { - return baselineHits; - } - - public long getBaselineCalls() { - return baselineInvocations; - } -} diff --git a/src/main/java/com/overops/plugins/bamboo/model/OverOpsReportModel.java b/src/main/java/com/overops/plugins/bamboo/model/OverOpsReportModel.java deleted file mode 100644 index 59f1a5f..0000000 --- a/src/main/java/com/overops/plugins/bamboo/model/OverOpsReportModel.java +++ /dev/null @@ -1,284 +0,0 @@ -package com.overops.plugins.bamboo.model; - -import java.util.List; - -public class OverOpsReportModel { - private boolean unstable; - private boolean markedUnstable; - private boolean passedNewErrorGate; - private boolean checkNewEvents; - private boolean passedResurfacedErrorGate; - private boolean checkResurfacedEvents; - private boolean checkCriticalErrors; - private boolean passedCriticalErrorGate; - private boolean checkTotalErrors; - private boolean passedTotalErrorGate; - private boolean checkUniqueErrors; - private boolean hasTopErrors; - private boolean passedUniqueErrorGate; - private boolean checkRegressedErrors; - private boolean passedRegressedEvents; - - private String summary; - private String newErrorSummary; - private String resurfacedErrorSummary; - private String criticalErrorSummary; - private String totalErrorSummary; - private String uniqueErrorSummary; - private String regressionSumarry; - - private List newEvents; - private List resurfacedEvents; - private List criticalEvents; - private List topEvents; - private List regressedEvents; - - public boolean isUnstable() { - return unstable; - } - - public void setUnstable(boolean unstable) { - this.unstable = unstable; - } - - public boolean isMarkedUnstable() { - return markedUnstable; - } - - public void setMarkedUnstable(boolean markedUnstable) { - this.markedUnstable = markedUnstable; - } - - public boolean isPassedNewErrorGate() { - return passedNewErrorGate; - } - - public void setPassedNewErrorGate(boolean passedNewErrorGate) { - this.passedNewErrorGate = passedNewErrorGate; - } - - public boolean isCheckNewEvents() { - return checkNewEvents; - } - - public void setCheckNewEvents(boolean checkNewEvents) { - this.checkNewEvents = checkNewEvents; - } - - public boolean isPassedResurfacedErrorGate() { - return passedResurfacedErrorGate; - } - - public void setPassedResurfacedErrorGate(boolean passedResurfacedErrorGate) { - this.passedResurfacedErrorGate = passedResurfacedErrorGate; - } - - public boolean isCheckResurfacedEvents() { - return checkResurfacedEvents; - } - - public void setCheckResurfacedEvents(boolean checkResurfacedEvents) { - this.checkResurfacedEvents = checkResurfacedEvents; - } - - public boolean isCheckCriticalErrors() { - return checkCriticalErrors; - } - - public void setCheckCriticalErrors(boolean checkCriticalErrors) { - this.checkCriticalErrors = checkCriticalErrors; - } - - public boolean isPassedCriticalErrorGate() { - return passedCriticalErrorGate; - } - - public void setPassedCriticalErrorGate(boolean passedCriticalErrorGate) { - this.passedCriticalErrorGate = passedCriticalErrorGate; - } - - public boolean isCheckTotalErrors() { - return checkTotalErrors; - } - - public void setCheckTotalErrors(boolean checkTotalErrors) { - this.checkTotalErrors = checkTotalErrors; - } - - public boolean isPassedTotalErrorGate() { - return passedTotalErrorGate; - } - - public void setPassedTotalErrorGate(boolean passedTotalErrorGate) { - this.passedTotalErrorGate = passedTotalErrorGate; - } - - public boolean isCheckUniqueErrors() { - return checkUniqueErrors; - } - - public void setCheckUniqueErrors(boolean checkUniqueErrors) { - this.checkUniqueErrors = checkUniqueErrors; - } - - public boolean isHasTopErrors() { - return hasTopErrors; - } - - public void setHasTopErrors(boolean hasTopErrors) { - this.hasTopErrors = hasTopErrors; - } - - public boolean isPassedUniqueErrorGate() { - return passedUniqueErrorGate; - } - - public void setPassedUniqueErrorGate(boolean passedUniqueErrorGate) { - this.passedUniqueErrorGate = passedUniqueErrorGate; - } - - public boolean isCheckRegressedErrors() { - return checkRegressedErrors; - } - - public void setCheckRegressedErrors(boolean checkRegressedErrors) { - this.checkRegressedErrors = checkRegressedErrors; - } - - public boolean isPassedRegressedEvents() { - return passedRegressedEvents; - } - - public void setPassedRegressedEvents(boolean passedRegressedEvents) { - this.passedRegressedEvents = passedRegressedEvents; - } - - public String getSummary() { - return summary; - } - - public void setSummary(String summary) { - this.summary = summary; - } - - public String getNewErrorSummary() { - return newErrorSummary; - } - - public void setNewErrorSummary(String newErrorSummary) { - this.newErrorSummary = newErrorSummary; - } - - public String getTotalErrorSummary() { - return totalErrorSummary; - } - - public void setTotalErrorSummary(String totalErrorSummary) { - this.totalErrorSummary = totalErrorSummary; - } - - public List getNewEvents() { - return newEvents; - } - - public void setNewEvents(List newEvents) { - this.newEvents = newEvents; - } - - public String getResurfacedErrorSummary() { - return resurfacedErrorSummary; - } - - public void setResurfacedErrorSummary(String resurfacedErrorSummary) { - this.resurfacedErrorSummary = resurfacedErrorSummary; - } - - public String getUniqueErrorSummary() { - return uniqueErrorSummary; - } - - public void setUniqueErrorSummary(String uniqueErrorSummary) { - this.uniqueErrorSummary = uniqueErrorSummary; - } - - public String getRegressionSumarry() { - return regressionSumarry; - } - - public void setRegressionSumarry(String regressionSumarry) { - this.regressionSumarry = regressionSumarry; - } - - public List getResurfacedEvents() { - return resurfacedEvents; - } - - public void setResurfacedEvents(List resurfacedEvents) { - this.resurfacedEvents = resurfacedEvents; - } - - public String getCriticalErrorSummary() { - return criticalErrorSummary; - } - - public void setCriticalErrorSummary(String criticalErrorSummary) { - this.criticalErrorSummary = criticalErrorSummary; - } - - public List getCriticalEvents() { - return criticalEvents; - } - - public void setCriticalEvents(List criticalEvents) { - this.criticalEvents = criticalEvents; - } - - public List getTopEvents() { - return topEvents; - } - - public void setTopEvents(List topEvents) { - this.topEvents = topEvents; - } - - public List getRegressedEvents() { - return regressedEvents; - } - - public void setRegressedEvents(List regressedEvents) { - this.regressedEvents = regressedEvents; - } - - @Override - public String toString() { - return "OverOpsReportModel{" + - "unstable=" + unstable + - ", markedUnstable=" + markedUnstable + - ", passedNewErrorGate=" + passedNewErrorGate + - ", checkNewEvents=" + checkNewEvents + - ", passedResurfacedErrorGate=" + passedResurfacedErrorGate + - ", checkResurfacedEvents=" + checkResurfacedEvents + - ", checkCriticalErrors=" + checkCriticalErrors + - ", passedCriticalErrorGate=" + passedCriticalErrorGate + - ", checkTotalErrors=" + checkTotalErrors + - ", passedTotalErrorGate=" + passedTotalErrorGate + - ", checkUniqueErrors=" + checkUniqueErrors + - ", hasTopErrors=" + hasTopErrors + - ", passedUniqueErrorGate=" + passedUniqueErrorGate + - ", checkRegressedErrors=" + checkRegressedErrors + - ", passedRegressedEvents=" + passedRegressedEvents + - ", summary='" + summary + '\'' + - ", newErrorSummary='" + newErrorSummary + '\'' + - ", resurfacedErrorSummary='" + resurfacedErrorSummary + '\'' + - ", criticalErrorSummary='" + criticalErrorSummary + '\'' + - ", totalErrorSummary='" + totalErrorSummary + '\'' + - ", uniqueErrorSummary='" + uniqueErrorSummary + '\'' + - ", regressionSumarry='" + regressionSumarry + '\'' + - ", newEvents=" + newEvents + - ", resurfacedEvents=" + resurfacedEvents + - ", criticalEvents=" + criticalEvents + - ", topEvents=" + topEvents + - ", regressedEvents=" + regressedEvents + - '}'; - } -} diff --git a/src/main/java/com/overops/plugins/bamboo/model/QueryOverOps.java b/src/main/java/com/overops/plugins/bamboo/model/QueryOverOps.java deleted file mode 100644 index ca4fb88..0000000 --- a/src/main/java/com/overops/plugins/bamboo/model/QueryOverOps.java +++ /dev/null @@ -1,231 +0,0 @@ -package com.overops.plugins.bamboo.model; - -import java.util.Map; - -import com.atlassian.bamboo.configuration.ConfigurationMap; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; - -import static com.overops.plugins.bamboo.configuration.Const.*; - -public class QueryOverOps { - private String apiUrl; - private String envId; - private String apiToken; - - private String applicationName; - private String deploymentName; - private String regexFilter; - private boolean markUnstable; - private Integer topErrorCount; - - private boolean newEvents; - private boolean resurfacedErrors; - private Integer maxErrorVolume; - private Integer maxUniqueErrors; - private String criticalExceptionTypes; - private String activeTimespan; - private String baselineTimespan; - private Integer minVolumeThreshold; - private Double minRateThreshold; - private Double regressionDelta; - private Double criticalRegressionThreshold; - private boolean applySeasonality; - - private boolean debug; - - public String getApiUrl() { - return apiUrl; - } - - public void setApiUrl(String apiUrl) { - this.apiUrl = apiUrl; - } - - public String getEnvId() { - return envId; - } - - public void setEnvId(String envId) { - this.envId = envId.toUpperCase(); // must be S12345, not s12345 - } - - public String getApiToken() { - return apiToken; - } - - public void setApiToken(String apiToken) { - this.apiToken = apiToken; - } - - public String getApplicationName() { - return applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public String getDeploymentName() { - return deploymentName; - } - - public void setDeploymentName(String deploymentName) { - this.deploymentName = deploymentName; - } - - public String getRegexFilter() { - return regexFilter; - } - - public void setRegexFilter(String regexFilter) { - this.regexFilter = regexFilter; - } - - public boolean isMarkUnstable() { - return markUnstable; - } - - public void setMarkUnstable(boolean markUnstable) { - this.markUnstable = markUnstable; - } - - public Integer getTopErrorCount() { - return topErrorCount; - } - - public void setTopErrorCount(Integer topErrorCount) { - this.topErrorCount = topErrorCount; - } - - public boolean isNewEvents() { - return newEvents; - } - - public void setNewEvents(boolean newEvents) { - this.newEvents = newEvents; - } - - public boolean isResurfacedErrors() { - return resurfacedErrors; - } - - public void setResurfacedErrors(boolean resurfacedErrors) { - this.resurfacedErrors = resurfacedErrors; - } - - public Integer getMaxErrorVolume() { - return maxErrorVolume; - } - - public void setMaxErrorVolume(Integer maxErrorVolume) { - this.maxErrorVolume = maxErrorVolume; - } - - public Integer getMaxUniqueErrors() { - return maxUniqueErrors; - } - - public void setMaxUniqueErrors(Integer maxUniqueErrors) { - this.maxUniqueErrors = maxUniqueErrors; - } - - public String getCriticalExceptionTypes() { - return criticalExceptionTypes; - } - - public void setCriticalExceptionTypes(String criticalExceptionTypes) { - this.criticalExceptionTypes = criticalExceptionTypes; - } - - public String getActiveTimespan() { - return activeTimespan; - } - - public void setActiveTimespan(String activeTimespan) { - this.activeTimespan = activeTimespan; - } - - public String getBaselineTimespan() { - return baselineTimespan; - } - - public void setBaselineTimespan(String baselineTimespan) { - this.baselineTimespan = baselineTimespan; - } - - public Integer getMinVolumeThreshold() { - return minVolumeThreshold; - } - - public void setMinVolumeThreshold(Integer minVolumeThreshold) { - this.minVolumeThreshold = minVolumeThreshold; - } - - public Double getMinRateThreshold() { - return minRateThreshold; - } - - public void setMinRateThreshold(Double minRateThreshold) { - this.minRateThreshold = minRateThreshold; - } - - public Double getRegressionDelta() { - return regressionDelta; - } - - public void setRegressionDelta(Double regressionDelta) { - this.regressionDelta = regressionDelta; - } - - public Double getCriticalRegressionThreshold() { - return criticalRegressionThreshold; - } - - public void setCriticalRegressionThreshold(Double criticalRegressionThreshold) { - this.criticalRegressionThreshold = criticalRegressionThreshold; - } - - public boolean isApplySeasonality() { - return applySeasonality; - } - - public void setApplySeasonality(boolean applySeasonality) { - this.applySeasonality = applySeasonality; - } - - public boolean isDebug() { - return debug; - } - - public void setDebug(boolean debug) { - this.debug = debug; - } - - @Override - public String toString() { - return "QueryOverOps{" + - "apiUrl='" + apiUrl + '\'' + - ", envId='" + envId + '\'' + - ", apiToken='" + apiToken + '\'' + - ", applicationName='" + applicationName + '\'' + - ", deploymentName='" + deploymentName + '\'' + - ", regexFilter='" + regexFilter + '\'' + - ", markUnstable=" + markUnstable + - ", topErrorCount=" + topErrorCount + - ", newEvents=" + newEvents + - ", resurfacedErrors=" + resurfacedErrors + - ", maxErrorVolume=" + maxErrorVolume + - ", maxUniqueErrors=" + maxUniqueErrors + - ", criticalExceptionTypes='" + criticalExceptionTypes + '\'' + - ", activeTimespan='" + activeTimespan + '\'' + - ", baselineTimespan='" + baselineTimespan + '\'' + - ", minVolumeThreshold=" + minVolumeThreshold + - ", minRateThreshold=" + minRateThreshold + - ", regressionDelta=" + regressionDelta + - ", criticalRegressionThreshold=" + criticalRegressionThreshold + - ", applySeasonality=" + applySeasonality + - ", debug=" + debug + - '}'; - } -} diff --git a/src/main/java/com/overops/plugins/bamboo/model/ReportEventModel.java b/src/main/java/com/overops/plugins/bamboo/model/ReportEventModel.java deleted file mode 100644 index 3e7d9a2..0000000 --- a/src/main/java/com/overops/plugins/bamboo/model/ReportEventModel.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.overops.plugins.bamboo.model; - -public class ReportEventModel { - private String arcLink; - private String type; - private String applications; - private String introducedBy; - private String eventSummary; - private String eventRate; - private long hits; - private long calls; - - public ReportEventModel() { - } - - public ReportEventModel(String arcLink, String type, String introducedBy) { - this.arcLink = arcLink; - this.type = type; - this.introducedBy = introducedBy; - } - - public ReportEventModel(String arcLink, String type, String introducedBy, String eventSummary, String eventRate, long hits, long calls, String applications) { - this.arcLink = arcLink; - this.type = type; - this.introducedBy = introducedBy; - this.eventSummary = eventSummary; - this.eventRate = eventRate; - this.hits = hits; - this.calls = calls; - this.applications = applications; - } - - public String getArcLink() { - return arcLink; - } - - public void setArcLink(String arcLink) { - this.arcLink = arcLink; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getApplications() { - return applications; - } - - public void setApplications(String applications) { - this.applications = applications; - } - - public String getIntroducedBy() { - return introducedBy; - } - - public void setIntroducedBy(String introducedBy) { - this.introducedBy = introducedBy; - } - - public String getEventSummary() { - return eventSummary; - } - - public void setEventSummary(String eventSummary) { - this.eventSummary = eventSummary; - } - - public String getEventRate() { - return eventRate; - } - - public void setEventRate(String eventRate) { - this.eventRate = eventRate; - } - - public long getHits() { - return hits; - } - - public void setHits(long hits) { - this.hits = hits; - } - - public long getCalls() { - return calls; - } - - public void setCalls(long calls) { - this.calls = calls; - } -} diff --git a/src/main/java/com/overops/plugins/bamboo/model/ReportRegressedModel.java b/src/main/java/com/overops/plugins/bamboo/model/ReportRegressedModel.java deleted file mode 100644 index bde8fa6..0000000 --- a/src/main/java/com/overops/plugins/bamboo/model/ReportRegressedModel.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.overops.plugins.bamboo.model; - -public class ReportRegressedModel extends ReportEventModel { - private long baselineHits; - private long baselineInvocations; - private String eventRate; - - public long getBaselineHits() { - return baselineHits; - } - - public void setBaselineHits(long baselineHits) { - this.baselineHits = baselineHits; - } - - public long getBaselineInvocations() { - return baselineInvocations; - } - - public void setBaselineInvocations(long baselineInvocations) { - this.baselineInvocations = baselineInvocations; - } - - public String getEventRate() { - return eventRate; - } - - public void setEventRate(String eventRate) { - this.eventRate = eventRate; - } -} diff --git a/src/main/java/com/overops/plugins/bamboo/service/OverOpsService.java b/src/main/java/com/overops/plugins/bamboo/service/OverOpsService.java deleted file mode 100644 index ace12cd..0000000 --- a/src/main/java/com/overops/plugins/bamboo/service/OverOpsService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.overops.plugins.bamboo.service; - - - -import com.atlassian.bamboo.build.logger.BuildLogger; -import com.overops.plugins.bamboo.model.QueryOverOps; -import com.overops.plugins.bamboo.service.impl.ReportBuilder; - -import java.io.IOException; - -public interface OverOpsService { - ReportBuilder.QualityReport perform(QueryOverOps queryOverOps, BuildLogger logger) throws IOException, InterruptedException; -} diff --git a/src/main/java/com/overops/plugins/bamboo/service/impl/OverOpsServiceImpl.java b/src/main/java/com/overops/plugins/bamboo/service/impl/OverOpsServiceImpl.java deleted file mode 100644 index 6410c9e..0000000 --- a/src/main/java/com/overops/plugins/bamboo/service/impl/OverOpsServiceImpl.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.overops.plugins.bamboo.service.impl; - -import com.atlassian.bamboo.build.logger.BuildLogger; -import com.overops.plugins.bamboo.model.QueryOverOps; -import com.overops.plugins.bamboo.service.OverOpsService; -import com.takipi.api.client.RemoteApiClient; -import com.takipi.api.client.data.view.SummarizedView; -import com.takipi.api.client.observe.Observer; -import com.takipi.api.client.util.regression.RegressionInput; -import com.takipi.api.client.util.view.ViewUtil; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -import java.io.IOException; -import java.io.PrintStream; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.regex.Pattern; - -@Component -public class OverOpsServiceImpl implements OverOpsService { - private static final String SEPARATOR = ","; - private boolean runRegressions = false; - - @Override - public ReportBuilder.QualityReport perform(QueryOverOps queryOverOps, BuildLogger logger) throws IOException, InterruptedException { - PrintStream printStream; - if (convertToMinutes(queryOverOps.getBaselineTimespan()) > 0) { - runRegressions = true; - } - if (queryOverOps.isDebug()) { - printStream = new BambooPrintWriter(System.out, logger); - } else { - printStream = null; - } - - // pauseForTheCause(printStream); - - validateInputs(queryOverOps, printStream); - - RemoteApiClient apiClient = (RemoteApiClient) RemoteApiClient.newBuilder().setHostname(queryOverOps.getApiUrl()).setApiKey(queryOverOps.getApiToken()).build(); - - if (Objects.nonNull(printStream) && (queryOverOps.isDebug())) { - apiClient.addObserver(new ApiClientObserver(printStream, queryOverOps.isDebug())); - } - - SummarizedView allEventsView = ViewUtil.getServiceViewByName(apiClient, queryOverOps.getEnvId(), "All Events"); - - if (Objects.isNull(allEventsView)) { - if(Objects.nonNull(printStream)) { - printStream.println("Could not acquire ID for 'All Events'. Please check connection to " + queryOverOps.getApiUrl()); - } - throw new IllegalStateException( - "Could not acquire ID for 'All Events'. Please check connection to " + queryOverOps.getApiUrl()); - } - - RegressionInput input = setupRegressionData(queryOverOps, allEventsView, printStream); - return ReportBuilder.execute(apiClient, input, queryOverOps.getMaxErrorVolume(), queryOverOps.getMaxUniqueErrors(), - queryOverOps.getTopErrorCount(), queryOverOps.getRegexFilter(), queryOverOps.isNewEvents(), queryOverOps.isResurfacedErrors(), - runRegressions, queryOverOps.isMarkUnstable(), printStream, queryOverOps.isDebug()); - - } - - //sleep for 30 seconds to ensure all data is in OverOps - // private static void pauseForTheCause(PrintStream printStream) { - // if (Objects.nonNull(printStream)) { - // printStream.println("Build Step: Starting OverOps Quality Gate...."); - // } - // try { - // Thread.sleep(30000); - // } catch (Exception e) { - // if (Objects.nonNull(printStream)) { - // printStream.println("Can not hold the process."); - // } - // } - // } - - private void validateInputs (QueryOverOps queryOverOps, PrintStream printStream) { - String apiHost = queryOverOps.getApiUrl(); - String apiKey = queryOverOps.getApiToken(); - - if (StringUtils.isEmpty(apiHost)) { - throw new IllegalArgumentException("Missing host name"); - } - - if (StringUtils.isEmpty(apiKey)) { - throw new IllegalArgumentException("Missing api key"); - } - - //validate active and baseline time window - if (!"0".equalsIgnoreCase(queryOverOps.getActiveTimespan())) { - if (convertToMinutes(queryOverOps.getActiveTimespan()) == 0) { - printStream.println("For Increasing Error Gate, the active timewindow currently set to: " + queryOverOps.getActiveTimespan() + " is not properly formated. See help for format instructions."); - throw new IllegalArgumentException("For Increasing Error Gate, the active timewindow currently set to: " + queryOverOps.getActiveTimespan() + " is not properly formated. See help for format instructions."); - } - } - if (!"0".equalsIgnoreCase(queryOverOps.getBaselineTimespan())) { - if (convertToMinutes(queryOverOps.getBaselineTimespan()) == 0) { - printStream.println("For Increasing Error Gate, the baseline timewindow currently set to: " + queryOverOps.getBaselineTimespan() + " cannot be zero or is improperly formated. See help for format instructions."); - throw new IllegalArgumentException("For Increasing Error Gate, the baseline timewindow currently set to: " + queryOverOps.getBaselineTimespan() + " cannot be zero or is improperly formated. See help for format instructions."); - } - } - - - if (StringUtils.isEmpty(queryOverOps.getEnvId())) { - throw new IllegalArgumentException("Missing environment Id"); - } - - } - - private RegressionInput setupRegressionData(QueryOverOps queryOverOps, SummarizedView allEventsView, PrintStream printStream) - throws InterruptedException, IOException { - - RegressionInput input = new RegressionInput(); - input.serviceId = queryOverOps.getEnvId(); - input.viewId = allEventsView.id; - input.applictations = parseArrayString(queryOverOps.getApplicationName(), printStream, "Application Name"); - input.deployments = parseArrayString(queryOverOps.getDeploymentName(), printStream, "Deployment Name"); - input.criticalExceptionTypes = parseArrayString(queryOverOps.getCriticalExceptionTypes(), printStream, - "Critical Exception Types"); - - if (runRegressions) { - input.activeTimespan = convertToMinutes(queryOverOps.getActiveTimespan()); - input.baselineTime = queryOverOps.getBaselineTimespan(); - input.baselineTimespan = convertToMinutes(queryOverOps.getBaselineTimespan()); - input.minVolumeThreshold = queryOverOps.getMinVolumeThreshold(); - input.minErrorRateThreshold = queryOverOps.getMinRateThreshold(); - input.regressionDelta = queryOverOps.getRegressionDelta(); - input.criticalRegressionDelta = queryOverOps.getCriticalRegressionThreshold(); - input.applySeasonality = queryOverOps.isApplySeasonality(); - input.validate(); - } - - printInputs(queryOverOps, printStream, input); - - return input; - } - - private int convertToMinutes(String timeWindow) { - - if (StringUtils.isEmpty(timeWindow)) { - return 0; - } - - if (timeWindow.toLowerCase().contains("d")) { - int days = Integer.parseInt(timeWindow.substring(0, timeWindow.indexOf("d"))); - return days * 24 * 60; - } else if (timeWindow.toLowerCase().contains("h")) { - int hours = Integer.parseInt(timeWindow.substring(0, timeWindow.indexOf("h"))); - return hours * 60; - } else if (timeWindow.toLowerCase().contains("m")) { - return Integer.parseInt(timeWindow.substring(0, timeWindow.indexOf("m"))); - } - - return 0; - } - - private static Collection parseArrayString(String value, PrintStream printStream, String name) { - if (StringUtils.isEmpty(value)) { - return Collections.emptySet(); - } - - return Arrays.asList(value.trim().split(Pattern.quote(SEPARATOR))); - } - - private void printInputs(QueryOverOps queryOverOps, PrintStream printStream, RegressionInput input) { - - if (Objects.nonNull(printStream)) { - printStream.println(input); - - printStream.println("Max unique errors = " + queryOverOps.getMaxUniqueErrors()); - printStream.println("Max error volume = " + queryOverOps.getMaxErrorVolume()); - printStream.println("Check new errors = " + queryOverOps.isNewEvents()); - printStream.println("Check resurfaced errors = " + queryOverOps.isResurfacedErrors()); - - String regexPrint; - - if (Objects.nonNull(queryOverOps.getRegexFilter())) { - regexPrint = queryOverOps.getRegexFilter(); - } else { - regexPrint = ""; - } - - printStream.println("Regex filter = " + regexPrint); - } - } - - protected static class ApiClientObserver implements Observer { - - private final PrintStream printStream; - private final boolean verbose; - - public ApiClientObserver(PrintStream printStream, boolean verbose) { - this.printStream = printStream; - this.verbose = verbose; - } - - @Override - public void observe(Operation operation, String url, String request, String response, int responseCode, long time) { - StringBuilder output = new StringBuilder(); - - output.append(String.valueOf(operation)); - output.append(" took "); - output.append(time / 1000); - output.append("ms for "); - output.append(url); - - if (verbose) { - output.append(". Response: "); - output.append(response); - } - - printStream.println(output.toString()); - } - } -} diff --git a/src/main/java/com/overops/plugins/bamboo/service/impl/ReportBuilder.java b/src/main/java/com/overops/plugins/bamboo/service/impl/ReportBuilder.java deleted file mode 100644 index 802bff7..0000000 --- a/src/main/java/com/overops/plugins/bamboo/service/impl/ReportBuilder.java +++ /dev/null @@ -1,452 +0,0 @@ -package com.overops.plugins.bamboo.service.impl; - -import com.overops.plugins.bamboo.model.OOReportRegressedEvent; -import com.google.gson.Gson; -import com.takipi.api.client.ApiClient; -import com.takipi.api.client.result.event.EventResult; -import com.takipi.api.client.util.cicd.OOReportEvent; -import com.takipi.api.client.util.cicd.ProcessQualityGates; -import com.takipi.api.client.util.cicd.QualityGateReport; -import com.takipi.api.client.util.regression.*; - -import java.io.PrintStream; -import java.util.*; -import java.util.regex.Pattern; - -public class ReportBuilder { - - public static class QualityReport { - - private final List newIssues; - private final List regressions; - private final List criticalErrors; - private final List topErrors; - private final List resurfacedErrors; - private final List allIssues; - private final boolean unstable; - private final RegressionInput input; - private final RateRegression regression; - private final long eventVolume; - private final int uniqueEventsCount; - private final boolean checkNewGate; - private final boolean checkResurfacedGate; - private final boolean checkCriticalGate; - private final boolean checkVolumeGate; - private final boolean checkUniqueGate; - private final boolean checkRegressionGate; - private final Integer maxEventVolume; - private final Integer maxUniqueVolume; - private final boolean markedUnstable; - - protected QualityReport(RegressionInput input, RateRegression regression, - List regressions, List criticalErrors, - List topErrors, List newIssues, - List resurfacedErrors, long eventVolume, int uniqueEventCounts, boolean unstable, - boolean checkNewGate, boolean checkResurfacedGate, boolean checkCriticalGate, boolean checkVolumeGate, - boolean checkUniqueGate, boolean checkRegressionGate, Integer maxEventVolume, Integer maxUniqueVolume, boolean markedUnstable) { - - this.input = input; - this.regression = regression; - - this.regressions = regressions; - this.allIssues = new ArrayList(); - this.newIssues = newIssues; - this.criticalErrors = criticalErrors; - this.topErrors = topErrors; - this.resurfacedErrors = resurfacedErrors; - - if (regressions != null) { - allIssues.addAll(regressions); - } - - this.eventVolume = eventVolume; - this.uniqueEventsCount = uniqueEventCounts; - this.unstable = unstable; - this.checkNewGate = checkNewGate; - this.checkResurfacedGate = checkResurfacedGate; - this.checkCriticalGate = checkCriticalGate; - this.checkVolumeGate = checkVolumeGate; - this.checkUniqueGate = checkUniqueGate; - this.checkRegressionGate = checkRegressionGate; - this.maxEventVolume = maxEventVolume; - this.maxUniqueVolume = maxUniqueVolume; - this.markedUnstable = markedUnstable; - } - - public RegressionInput getInput() { - return input; - } - - public RateRegression getRegression() { - return regression; - } - - public List getResurfacedErrors() { - return resurfacedErrors; - } - - public List getAllIssues() { - return allIssues; - } - - public List getCriticalErrors() { - return criticalErrors; - } - - public List getTopErrors() { - return topErrors; - } - - public List getNewIssues() { - return newIssues; - } - - public List getRegressions() { - return regressions; - } - - public long getUniqueEventsCount() { - return uniqueEventsCount; - } - - public boolean getUnstable() { - return unstable; - } - - public long getEventVolume() { - return eventVolume; - } - - public boolean isCheckNewGate() { - return checkNewGate; - } - - public boolean isCheckResurfacedGate() { - return checkResurfacedGate; - } - - public boolean isCheckCriticalGate() { - return checkCriticalGate; - } - - public boolean isCheckVolumeGate() { - return checkVolumeGate; - } - - public boolean isCheckUniqueGate() { - return checkUniqueGate; - } - - public boolean isCheckRegressionGate() { - return checkRegressionGate; - } - - public Integer getMaxEventVolume() { - return maxEventVolume; - } - - public Integer getMaxUniqueVolume() { - return maxUniqueVolume; - } - - public boolean isMarkedUnstable() { - return markedUnstable; - } - - public String getDeploymentName() { - if (Objects.nonNull(getInput()) && Objects.nonNull(getInput().deployments)) { - String value = getInput().deployments.toString(); - value = value.replace("[", ""); - value = value.replace("]", ""); - return value; - } - return ""; - } - } - - private static class ReportVolume { - protected List topEvents; - protected Collection filter; - - } - - private static boolean allowEvent(EventResult event, Pattern pattern) { - - if (pattern == null ) { - return true; - } - - String json = new Gson().toJson(event); - boolean result = !pattern.matcher(json).find(); - - return result; - } - - private static List getSortedEventsByVolume(Collection events) { - - List result = new ArrayList(events); - - result.sort((o1, o2) -> { - long v1; - long v2; - - if (o1.stats != null) { - v1 = o1.stats.hits; - } else { - v1 = 0; - } - - if (o2.stats != null) { - v2 = o2.stats.hits; - } else { - v2 = 0; - } - - return (int)(v2 - v1); - }); - - return result; - } - - private static void addEvent(Set events, EventResult event, - Pattern pattern, PrintStream output, boolean verbose) { - - if (allowEvent(event, pattern)) { - events.add(event); - } else if ((output != null) && (verbose)) { - output.println(event + " did not match regexFilter and was skipped"); - } - } - - private static Collection filterEvents(RateRegression rateRegression, - Pattern pattern, PrintStream output, boolean verbose) { - - Set result = new HashSet<>(); - - if (pattern != null) { - - for (EventResult event : rateRegression.getNonRegressions()) { - addEvent(result, event, pattern, output, verbose); - } - - for (EventResult event : rateRegression.getAllNewEvents().values()) { - addEvent(result, event, pattern, output, verbose); - } - - for (RegressionResult regressionResult : rateRegression.getAllRegressions().values()) { - addEvent(result, regressionResult.getEvent(), pattern, output, verbose); - - } - - } else { - result.addAll(rateRegression.getNonRegressions()); - result.addAll(rateRegression.getAllNewEvents().values()); - - for (RegressionResult regressionResult : rateRegression.getAllRegressions().values()) { - result.add(regressionResult.getEvent()); - } - } - - return result; - } - - private static ReportVolume getReportVolume(ApiClient apiClient, - RegressionInput input, RateRegression rateRegression, - int limit, String regexFilter, PrintStream output, boolean verbose) { - - ReportVolume result = new ReportVolume(); - - Pattern pattern; - - if ((regexFilter != null) && (regexFilter.length() > 0)) { - pattern = Pattern.compile(regexFilter); - } else { - pattern = null; - } - - Collection eventsSet = filterEvents(rateRegression, pattern, output, verbose); - List events = getSortedEventsByVolume(eventsSet); - - if (pattern != null) { - result.filter = eventsSet; - } - - result.topEvents = new ArrayList<>(); - - for (EventResult event : events) { - if (event.stats != null) { - if (result.topEvents.size() < limit) { - String arcLink = ProcessQualityGates.getArcLink(apiClient, event.id, input, rateRegression.getActiveWndowStart()); - result.topEvents.add(new OOReportEvent(event, arcLink)); - } - } - } - - return result; - } - - /* - * Entry point into report engine - */ - public static QualityReport execute(ApiClient apiClient, RegressionInput input, - Integer maxEventVolume, Integer maxUniqueErrors, int topEventLimit, String regexFilter, - boolean newEvents, boolean resurfacedEvents, boolean runRegressions, boolean markedUnstable, PrintStream output, boolean verbose) { - - //check if total or unique gates are being tested - boolean countGate = false; - if (maxEventVolume != 0 || maxUniqueErrors != 0) { - countGate = true; - } - boolean checkMaxEventGate = maxEventVolume != 0; - boolean checkUniqueEventGate = maxUniqueErrors != 0; - - //get the CICD quality report for all gates but Regressions - //initialize the QualityGateReport so we don't get null pointers below - QualityGateReport qualityGateReport = new QualityGateReport(); - if (countGate || newEvents || resurfacedEvents || regexFilter != null) { - qualityGateReport = ProcessQualityGates.processCICDInputs(apiClient, input, newEvents, resurfacedEvents, - regexFilter, topEventLimit, countGate, output, verbose); - } - - //run the regression gate - ReportVolume reportVolume; - RateRegression rateRegression = null; - List regressions = null; - boolean hasRegressions = false; - if (runRegressions) { - rateRegression = RegressionUtil.calculateRateRegressions(apiClient, input, output, verbose); - - reportVolume = getReportVolume(apiClient, input, - rateRegression, topEventLimit, regexFilter, output, verbose); - - regressions = getAllRegressions(apiClient, input, rateRegression, reportVolume.filter); - if (regressions != null && regressions.size() > 0) { - hasRegressions = true; - replaceSourceId2(regressions); - } - } - - //max total error gate - boolean maxVolumeExceeded = (maxEventVolume != 0) && (qualityGateReport.getTotalErrorCount() > maxEventVolume); - - //max unique error gate - long uniqueEventCount; - boolean maxUniqueErrorsExceeded; - if (maxUniqueErrors != 0) { - uniqueEventCount = qualityGateReport.getUniqueErrorCount(); - maxUniqueErrorsExceeded = uniqueEventCount > maxUniqueErrors; - } else { - uniqueEventCount = 0; - maxUniqueErrorsExceeded = false; - } - - //new error gate - boolean newErrors = false; - if (qualityGateReport.getNewErrors() != null && qualityGateReport.getNewErrors().size() > 0) { - newErrors = true; - replaceSourceId(qualityGateReport.getNewErrors()); - } - - //resurfaced error gate - boolean resurfaced = false; - if (qualityGateReport.getResurfacedErrors() != null && qualityGateReport.getResurfacedErrors().size() > 0) { - resurfaced = true; - replaceSourceId(qualityGateReport.getResurfacedErrors()); - } - - //critical error gate - boolean critical = false; - if (qualityGateReport.getCriticalErrors() != null && qualityGateReport.getCriticalErrors().size() > 0) { - critical = true; - replaceSourceId(qualityGateReport.getCriticalErrors()); - } - - //top errors - if (qualityGateReport.getTopErrors() != null && qualityGateReport.getTopErrors().size() > 0) { - replaceSourceId(qualityGateReport.getTopErrors()); - } - - boolean checkCritical = false; - if (input.criticalExceptionTypes != null && input.criticalExceptionTypes.size() > 0) { - checkCritical = true; - } - - boolean unstable = (hasRegressions) - || (maxVolumeExceeded) - || (maxUniqueErrorsExceeded) - || (newErrors) - || (resurfaced) - || (critical); - - return new QualityReport(input, rateRegression, regressions, - qualityGateReport.getCriticalErrors(), qualityGateReport.getTopErrors(), qualityGateReport.getNewErrors(), - qualityGateReport.getResurfacedErrors(), qualityGateReport.getTotalErrorCount(), - qualityGateReport.getUniqueErrorCount(), unstable, newEvents, resurfacedEvents, checkCritical, checkMaxEventGate, - checkUniqueEventGate, runRegressions, maxEventVolume, maxUniqueErrors, markedUnstable); - } - - //for each event, replace the source ID in the ARC link with the number 4 (which means Jenkins) - private static void replaceSourceId (List events) { - for (OOReportEvent ooReportEvent : events) { - String arcLink = replaceSourceIdInArcLink(ooReportEvent.getARCLink()); - ooReportEvent.setArcLink(arcLink); - } - } - - //for each event, replace the source ID in the ARC link with the number 4 (which means Jenkins) - private static void replaceSourceId2 (List events) { - for (OOReportEvent ooReportEvent : events) { - String arcLink = replaceSourceIdInArcLink(ooReportEvent.getARCLink()); - ooReportEvent.setArcLink(arcLink); - } - } - - private static String replaceSourceIdInArcLink(String arcLink) { - if (arcLink == null) { - return arcLink; - } - String returnString; - CharSequence target = "source=43"; - CharSequence replacement = "source=4"; - - returnString = arcLink.replace(target, replacement); - - return returnString; - } - - private static List getAllRegressions(ApiClient apiClient, - RegressionInput input, RateRegression rateRegression, Collection filter) { - - List result = new ArrayList(); - - for (RegressionResult regressionResult : rateRegression.getCriticalRegressions().values()) { - - if ((filter != null) && (!filter.contains(regressionResult.getEvent()))) { - continue; - } - - String arcLink = ProcessQualityGates.getArcLink(apiClient, regressionResult.getEvent().id, input, rateRegression.getActiveWndowStart()); - - OOReportRegressedEvent regressedEvent = new OOReportRegressedEvent(regressionResult.getEvent(), - regressionResult.getBaselineHits(), regressionResult.getBaselineInvocations(), RegressionStringUtil.SEVERE_REGRESSION, arcLink); - - result.add(regressedEvent); - } - - for (RegressionResult regressionResult : rateRegression.getAllRegressions().values()) { - - if (rateRegression.getCriticalRegressions().containsKey(regressionResult.getEvent().id)) { - continue; - } - - String arcLink = ProcessQualityGates.getArcLink(apiClient, regressionResult.getEvent().id, input, rateRegression.getActiveWndowStart()); - - OOReportRegressedEvent regressedEvent = new OOReportRegressedEvent(regressionResult.getEvent(), - regressionResult.getBaselineHits(), regressionResult.getBaselineInvocations(), RegressionStringUtil.REGRESSION, arcLink); - - result.add(regressedEvent); - } - - return result; - } -} diff --git a/src/main/java/com/overops/plugins/bamboo/utils/ReportUtils.java b/src/main/java/com/overops/plugins/bamboo/utils/ReportUtils.java deleted file mode 100644 index d6cd997..0000000 --- a/src/main/java/com/overops/plugins/bamboo/utils/ReportUtils.java +++ /dev/null @@ -1,215 +0,0 @@ -package com.overops.plugins.bamboo.utils; - -import com.overops.plugins.bamboo.model.OverOpsReportModel; -import com.overops.plugins.bamboo.model.ReportEventModel; -import com.overops.plugins.bamboo.service.impl.ReportBuilder; -import com.takipi.api.client.util.cicd.OOReportEvent; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -public class ReportUtils { - - public static OverOpsReportModel copyResult(ReportBuilder.QualityReport report) { - OverOpsReportModel result = new OverOpsReportModel(); - result.setMarkedUnstable(report.isMarkedUnstable()); - result.setUnstable(report.getUnstable()); - result.setSummary(getSummary(report)); - result.setPassedNewErrorGate(getPassedNewErrorGate(report)); - result.setCheckNewEvents(getCheckNewEvents(report)); - result.setNewErrorSummary(getNewErrorSummary(report)); - result.setNewEvents(getNewEvents(report).stream().map(e -> new ReportEventModel(e.getARCLink(), e.getType(), e.getIntroducedBy(), e.getEventSummary(), e.getEventRate(), e.getHits(), e.getCalls(), e.getApplications())).collect(Collectors.toList())); - result.setPassedResurfacedErrorGate(getPassedResurfacedErrorGate(report)); - result.setCheckResurfacedEvents(getCheckResurfacedEvents(report)); - result.setResurfacedErrorSummary(getResurfacedErrorSummary(report)); - result.setResurfacedEvents(getResurfacedEvents(report).stream().map(e -> new ReportEventModel(e.getARCLink(), e.getType(), e.getIntroducedBy(), e.getEventSummary(), e.getEventRate(), e.getHits(), e.getCalls(), e.getApplications())).collect(Collectors.toList())); - result.setCheckCriticalErrors(getCheckCriticalErrors(report)); - result.setPassedCriticalErrorGate(getPassedCriticalErrorGate(report)); - result.setCriticalErrorSummary(getCriticalErrorSummary(report)); - result.setCriticalEvents(getCriticalEvents(report).stream().map(e -> new ReportEventModel(e.getARCLink(), e.getType(), e.getIntroducedBy(), e.getEventSummary(), e.getEventRate(), e.getHits(), e.getCalls(), e.getApplications())).collect(Collectors.toList())); - result.setCheckTotalErrors(getCheckTotalErrors(report)); - result.setPassedTotalErrorGate(getPassedTotalErrorGate(report)); - result.setTotalErrorSummary(getTotalErrorSummary(report)); - result.setCheckUniqueErrors(getCheckUniqueErrors(report)); - result.setHasTopErrors(getHasTopErrors(report)); - result.setPassedUniqueErrorGate(getPassedUniqueErrorGate(report)); - result.setUniqueErrorSummary(getUniqueErrorSummary(report)); - result.setTopEvents(getTopEvents(report).stream().map(e -> new ReportEventModel(e.getARCLink(), e.getType(), e.getIntroducedBy(), e.getEventSummary(), e.getEventRate(), e.getHits(), e.getCalls(), e.getApplications())).collect(Collectors.toList())); - result.setRegressionSumarry(getRegressionSumarry(report)); - result.setCheckRegressedErrors(getCheckRegressedErrors(report)); - result.setPassedRegressedEvents(getPassedRegressedEvents(report)); - result.setRegressedEvents(getRegressedEvents(report).stream().map(e -> new ReportEventModel(e.getARCLink(), e.getType(), e.getIntroducedBy(), e.getEventSummary(), e.getEventRate(), e.getHits(), e.getCalls(), e.getApplications())).collect(Collectors.toList())); - return result; - } - - private static String getDeploymentName(ReportBuilder.QualityReport report) { - return Optional.of(report.getInput()).filter(e -> Objects.nonNull(e.deployments)) - .map(e -> e.deployments).map(Object::toString).map(e -> e.replace("[", "")) - .map(e -> e.replace("]", "")).orElse(""); - } - - private static String getSummary(ReportBuilder.QualityReport report) { - if (report.getUnstable() && report.isMarkedUnstable()) { - //the build is unstable when marking the build as unstable - return "OverOps has marked build " + getDeploymentName(report) + " as unstable because the below quality gate(s) were not met."; - } else if (!report.isMarkedUnstable() && report.getUnstable()) { - //unstable build stable when NOT marking the build as unstable - return "OverOps has detected issues with build " + getDeploymentName(report) + " but did not mark the build as unstable."; - } else { - //stable build when marking the build as unstable - return "Congratulations, build " + getDeploymentName(report) + " has passed all quality gates!"; - } - } - - private static boolean getPassedNewErrorGate(ReportBuilder.QualityReport report) { - return getCheckNewEvents(report) && !getNewErrorsExist(report); - } - - private static boolean getCheckNewEvents(ReportBuilder.QualityReport report) { - return report.isCheckNewGate(); - } - - private static String getNewErrorSummary(ReportBuilder.QualityReport report) { - if (getNewEvents(report).size() > 0) { - return "New Error Gate: Failed, OverOps detected " + report.getNewIssues().size() + " new error(s) in your build."; - } else if (report.isCheckNewGate()) { - return "New Error Gate: Passed, OverOps did not detect any new errors in your build."; - } - - return null; - } - - private static boolean getNewErrorsExist(ReportBuilder.QualityReport report) { - return getNewEvents(report).size() > 0; - } - - private static List getNewEvents(ReportBuilder.QualityReport report) { - return Optional.ofNullable(report.getNewIssues()).orElse(new ArrayList<>()); - } - - private static boolean getPassedResurfacedErrorGate(ReportBuilder.QualityReport report) { - return getCheckResurfacedEvents(report) && !getResurfacedErrorsExist(report); - } - - private static boolean getResurfacedErrorsExist(ReportBuilder.QualityReport report) { - return getResurfacedEvents(report).size() > 0; - } - - private static boolean getCheckResurfacedEvents(ReportBuilder.QualityReport report) { - return report.isCheckResurfacedGate(); - } - - private static String getResurfacedErrorSummary(ReportBuilder.QualityReport report) { - if (getResurfacedEvents(report).size() > 0) { - return "Resurfaced Error Gate: Failed, OverOps detected " + report.getResurfacedErrors().size() + " resurfaced errors in your build."; - } else if (report.isCheckResurfacedGate()) { - return "Resurfaced Error Gate: Passed, OverOps did not detect any resurfaced errors in your build."; - } - - return null; - } - - private static List getResurfacedEvents(ReportBuilder.QualityReport report) { - return Optional.ofNullable(report.getResurfacedErrors()).orElse(new ArrayList<>()); - } - - private static boolean getCheckCriticalErrors(ReportBuilder.QualityReport report) { - return report.isCheckCriticalGate(); - } - - private static boolean getPassedCriticalErrorGate(ReportBuilder.QualityReport report) { - return getCheckCriticalErrors(report) && !getCriticalErrorsExist(report); - } - - private static boolean getCriticalErrorsExist(ReportBuilder.QualityReport report) { - return getCriticalEvents(report).size() > 0; - } - - private static String getCriticalErrorSummary(ReportBuilder.QualityReport report) { - if (getCriticalEvents(report).size() > 0) { - return "Critical Error Gate: Failed, OverOps detected " + report.getCriticalErrors().size() + " critical errors in your build."; - } else if (report.isCheckCriticalGate()) { - return "Critical Error Gate: Passed, OverOps did not detect any critical errors in your build."; - } - - return null; - } - - private static List getCriticalEvents(ReportBuilder.QualityReport report) { - return Optional.ofNullable(report.getCriticalErrors()).orElse(new ArrayList<>()); - } - - private static boolean getCountGates(ReportBuilder.QualityReport report) { - return getCheckUniqueErrors(report) || getCheckTotalErrors(report); - } - - private static boolean getCheckTotalErrors(ReportBuilder.QualityReport report) { - return report.isCheckVolumeGate(); - } - - private static boolean getPassedTotalErrorGate(ReportBuilder.QualityReport report) { - return getCheckTotalErrors(report) && (report.getEventVolume() > 0 && report.getEventVolume() < report.getMaxEventVolume()); - } - - private static String getTotalErrorSummary(ReportBuilder.QualityReport report) { - if (report.getEventVolume() > 0 && report.getEventVolume() >= report.getMaxEventVolume()) { - return "Total Error Volume Gate: Failed, OverOps detected " + report.getEventVolume() + " total errors which is >= the max allowable of " + report.getMaxEventVolume(); - } else if (report.getEventVolume() > 0 && report.getEventVolume() < report.getMaxEventVolume()) { - return "Total Error Volume Gate: Passed, OverOps detected " + report.getEventVolume() + " total errors which is < than max allowable of " + report.getMaxEventVolume(); - } - - return null; - } - - private static boolean getCheckUniqueErrors(ReportBuilder.QualityReport report) { - return report.isCheckUniqueGate(); - } - - private static boolean getHasTopErrors(ReportBuilder.QualityReport report) { - return !getPassedTotalErrorGate(report) || !getPassedUniqueErrorGate(report); - } - - private static boolean getPassedUniqueErrorGate(ReportBuilder.QualityReport report) { - return getCheckUniqueErrors(report) && (report.getUniqueEventsCount() > 0 && report.getUniqueEventsCount() < report.getMaxUniqueVolume()); - } - - private static String getUniqueErrorSummary(ReportBuilder.QualityReport report) { - if (report.getUniqueEventsCount() > 0 && report.getUniqueEventsCount() >= report.getMaxUniqueVolume()) { - return "Unique Error Volume Gate: Failed, OverOps detected " + report.getUniqueEventsCount() + " unique errors which is >= the max allowable of " + report.getMaxUniqueVolume(); - } else if (report.getUniqueEventsCount() > 0 && report.getUniqueEventsCount() < report.getMaxUniqueVolume()) { - return "Unique Error Volume Gate: Passed, OverOps detected " + report.getUniqueEventsCount() + " unique errors which is < than max allowable of " + report.getMaxUniqueVolume(); - } - - return null; - } - - private static List getTopEvents(ReportBuilder.QualityReport report) { - return Optional.ofNullable(report.getTopErrors()).orElse(new ArrayList<>()); - } - - private static String getRegressionSumarry(ReportBuilder.QualityReport report) { - String baselineTime = Objects.nonNull(report.getInput()) ? report.getInput().baselineTime : ""; - if (!getPassedRegressedEvents(report)) { - return "Increasing Quality Gate: Failed, OverOps detected increasing errors in the current build against the baseline of " + baselineTime; - } else if (getPassedRegressedEvents(report)) { - return "Increasing Quality Gate: Passed, OverOps did not detect any increasing errors in the current build against the baseline of " + baselineTime; - } - - return null; - } - - private static boolean getCheckRegressedErrors(ReportBuilder.QualityReport report) { - return report.isCheckRegressionGate(); - } - - private static boolean getPassedRegressedEvents(ReportBuilder.QualityReport report) { - return !(getCheckRegressedErrors(report) && report.getRegressions() != null && report.getRegressions().size() > 0); - } - - private static List getRegressedEvents(ReportBuilder.QualityReport report) { - return Optional.ofNullable(report.getAllIssues()).orElse(new ArrayList<>()); - } -} diff --git a/src/main/resources/com/overops/plugins/bamboo/overops.properties b/src/main/resources/com/overops/plugins/bamboo/overops.properties index da488e8..2e94199 100644 --- a/src/main/resources/com/overops/plugins/bamboo/overops.properties +++ b/src/main/resources/com/overops/plugins/bamboo/overops.properties @@ -14,6 +14,8 @@ com.overops.plugins.bamboo.task.config.deploymentName=Deployment Name com.overops.plugins.bamboo.task.config.envId=Environment ID com.overops.plugins.bamboo.task.config.regexFilter=Regex Filter com.overops.plugins.bamboo.task.config.markUnstable=Mark Build Unstable +com.overops.plugins.bamboo.task.config.showAllEvents=Show All Events +com.overops.plugins.bamboo.task.config.passOnQRException=Do not fail the build if OverOps reliability report fails to run. com.overops.plugins.bamboo.task.config.topErrorCount=Number of total and unique errors to show com.overops.plugins.bamboo.task.config.checkNewErrors=New Error Gate @@ -28,15 +30,6 @@ com.overops.plugins.bamboo.task.config.maxUniqueErrors=Max Allowable Unique Erro com.overops.plugins.bamboo.task.config.checkCriticalErrors=Critical Exception Type Gate com.overops.plugins.bamboo.task.config.criticalExceptionTypes=Detect Critical Exception Types -com.overops.plugins.bamboo.task.config.checkIncreasingErrors=Increasing Errors Gate -com.overops.plugins.bamboo.task.config.activeTimespan=Active Time Window -com.overops.plugins.bamboo.task.config.baselineTimespan=Baseline Time Window -com.overops.plugins.bamboo.task.config.minVolumeThreshold=Error Volume Threshold -com.overops.plugins.bamboo.task.config.minRateThreshold=Error Rate Threshold (0-1) -com.overops.plugins.bamboo.task.config.regressionDelta=Regression Delta (0-1) -com.overops.plugins.bamboo.task.config.criticalRegressionThreshold=Critical Regression Threshold (0-1) -com.overops.plugins.bamboo.task.config.applySeasonality=Apply Seasonality - com.overops.plugins.bamboo.task.config.debug=Debug Mode com.overops.plugins.bamboo.report.label=OverOps Quality Report diff --git a/src/main/resources/templates/editTaskConfig.ftl b/src/main/resources/templates/editTaskConfig.ftl index 249b7be..3bb7742 100644 --- a/src/main/resources/templates/editTaskConfig.ftl +++ b/src/main/resources/templates/editTaskConfig.ftl @@ -51,6 +51,8 @@ [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.topErrorCount" name="topErrorCount" required="false" description="The number of total and unique errors to show in the quality report, sorted by volume." /]
[@ww.checkbox labelKey="com.overops.plugins.bamboo.task.config.markUnstable" name="markUnstable" required="false" description="If checked the build will be marked unstable when any quality gates fail."/] +
+[@ww.checkbox labelKey="com.overops.plugins.bamboo.task.config.showAllEvents" name="showAllEvents" required="false" description="If checked the quality report will list events for both passed and failed quality gates, otherwise only events for failed gates will be displayed."/]

Quality Gate settings

[@ww.checkbox labelKey="com.overops.plugins.bamboo.task.config.checkNewErrors" name="checkNewErrors" required="false" description="Check if the current build has any new errors." /] @@ -81,22 +83,9 @@ [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.criticalExceptionTypes" name="criticalExceptionTypes" required="false" description="A comma delimited list of critical exception types. For example: NullPointerException,IndexOutOfBoundsException"/] -
- -
- - [@ww.checkbox labelKey="com.overops.plugins.bamboo.task.config.checkIncreasingErrors" name="checkIncreasingErrors" class="checkbox toggle-details" required="false" tabindex="-1" description="Use this Gate to detect increasing errors in your current build versus a given baseline."/] - - [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.activeTimespan" name="activeTimespan" required="false" description="The time window to search for new and increasing errors. Set to zero to use the entire deployment time window. Supported values are: d - day, h - hour, m - minute. For example: 12h"/] - [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.baselineTimespan" name="baselineTimespan" required="false" description="The time window against which events in the active window are compared to test for regressions. Supported values are: d - day, h - hour, m - minute. For example: 7d"/] - [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.minVolumeThreshold" name="minVolumeThreshold" required="false" description="The minimal number of times an event of a non-critical type must take place to be considered critical."/] - [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.minRateThreshold" name="minRateThreshold" required="false" description="The minimum rate at which event of a non-critical type must take place to be considered critical."/] - [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.regressionDelta" name="regressionDelta" required="false" description="The change in percentage between an event's rate in the active time span compared to the baseline to be considered a regression."/] - [@ww.textfield labelKey="com.overops.plugins.bamboo.task.config.criticalRegressionThreshold" name="criticalRegressionThreshold" required="false" description="The change in percentage between an event's rate in the active time span compared to the baseline to be considered a critical error."/] - [@ww.checkbox labelKey="com.overops.plugins.bamboo.task.config.applySeasonality" name="applySeasonality" required="false" description="If peaks have been seen in baseline window, then this would be considered normal and not a regression. If an equal or matching peak exists in the baseline time window, or two peaks of greater than 50% of the volume seen in the active window, the event will not be marked as a regression."/] -
-

Advanced settings

+[@ww.checkbox labelKey="com.overops.plugins.bamboo.task.config.passOnQRException" name="passOnQRException" required="false" description="If checked, inability to run the OverOps reliability report will not fail the build."/] +
[@ww.checkbox labelKey="com.overops.plugins.bamboo.task.config.debug" name="debug" required="false" description="If checked, all queries with results will be displayed in the OverOps reliability report. For debugging purposes only."/]