private List<QualityGateConditionDto> createBuiltInConditions(QualityGateDto qg) { List<QualityGateConditionDto> conditions = new ArrayList<>(); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_SECURITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, "80")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, "3")); return conditions; } }
private static void checkRatingMetric(MetricDto metric, String errorThreshold, List<String> errors) { if (!metric.getValueType().equals(RATING.name())) { return; } if (!isCoreRatingMetric(metric.getKey())) { errors.add(format("The metric '%s' cannot be used", metric.getShortName())); } if (!isValidRating(errorThreshold)) { addInvalidRatingError(errorThreshold, errors); return; } checkRatingGreaterThanOperator(errorThreshold, errors); }
private static void validateCondition(MetricDto metric, String operator, String errorThreshold) { List<String> errors = new ArrayList<>(); validateMetric(metric, errors); checkOperator(metric, operator, errors); checkErrorThreshold(metric, errorThreshold, errors); checkRatingMetric(metric, errorThreshold, errors); checkRequest(errors.isEmpty(), errors); }
private static void checkOperator(MetricDto metric, String operator, List<String> errors) { check( Condition.Operator.isValid(operator) && isAllowedOperator(operator, metric), errors, "Operator %s is not allowed for this metric.", operator ); }
@Test public void fail_to_update_condition_on_rating_metric_on_not_core_rating_metric() { MetricDto metric = insertMetric(RATING, "not_core_rating_metric"); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, c -> c.setOperator("LT").setErrorThreshold("3")); expectedException.expect(BadRequestException.class); expectedException.expectMessage(format("The metric '%s' cannot be used", metric.getShortName())); underTest.updateCondition(db.getSession(), condition, metric.getKey(), "GT", "4"); }
public QualityGateConditionDto updateCondition(DbSession dbSession, QualityGateConditionDto condition, String metricKey, String operator, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period) { MetricDto metric = getNonNullMetric(dbSession, metricKey); validateCondition(metric, operator, warningThreshold, errorThreshold, period); checkConditionDoesNotAlreadyExistOnSameMetricAndPeriod(getConditions(dbSession, condition.getQualityGateId(), condition.getId()), metric, period); condition .setMetricId(metric.getId()) .setMetricKey(metric.getKey()) .setOperator(operator) .setWarningThreshold(warningThreshold) .setErrorThreshold(errorThreshold) .setPeriod(period); dbClient.gateConditionDao().update(condition, dbSession); return condition; }
private static void validateCondition(MetricDto metric, String operator, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period) { List<String> errors = new ArrayList<>(); validateMetric(metric, errors); checkOperator(metric, operator, errors); checkThresholds(warningThreshold, errorThreshold, errors); checkPeriod(metric, period, errors); validateThresholdValues(metric, warningThreshold, errors); validateThresholdValues(metric, errorThreshold, errors); checkRatingMetric(metric, warningThreshold, errorThreshold, period, errors); checkRequest(errors.isEmpty(), errors); }
public QualityGateConditionDto createCondition(DbSession dbSession, QualityGateDto qualityGate, String metricKey, String operator, String errorThreshold) { MetricDto metric = getNonNullMetric(dbSession, metricKey); validateCondition(metric, operator, errorThreshold); checkConditionDoesNotExistOnSameMetric(getConditions(dbSession, qualityGate.getId()), metric); QualityGateConditionDto newCondition = new QualityGateConditionDto().setQualityGateId(qualityGate.getId()) .setMetricId(metric.getId()).setMetricKey(metric.getKey()) .setOperator(operator) .setErrorThreshold(errorThreshold); dbClient.gateConditionDao().insert(newCondition, dbSession); return newCondition; }
private static void validateMetric(MetricDto metric, List<String> errors) { check(isAlertable(metric), errors, "Metric '%s' cannot be used to define a condition.", metric.getKey()); }
public QualityGateConditionDto updateCondition(DbSession dbSession, QualityGateConditionDto condition, String metricKey, String operator, String errorThreshold) { MetricDto metric = getNonNullMetric(dbSession, metricKey); validateCondition(metric, operator, errorThreshold); condition .setMetricId(metric.getId()) .setMetricKey(metric.getKey()) .setOperator(operator) .setErrorThreshold(errorThreshold); dbClient.gateConditionDao().update(condition, dbSession); return condition; }
private static void checkThresholds(@Nullable String warningThreshold, @Nullable String errorThreshold, List<String> errors) { check(warningThreshold != null || errorThreshold != null, errors, "At least one threshold (warning, error) must be set."); }
@Override public void handle(Request request, Response response) { int id = request.mandatoryParamAsInt(PARAM_ID); String metric = request.mandatoryParam(PARAM_METRIC); String operator = request.mandatoryParam(PARAM_OPERATOR); String error = request.mandatoryParam(PARAM_ERROR); try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); QualityGateConditionDto condition = wsSupport.getCondition(dbSession, id); QGateWithOrgDto qualityGateDto = dbClient.qualityGateDao().selectByOrganizationAndId(dbSession, organization, condition.getQualityGateId()); checkState(qualityGateDto != null, "Condition '%s' is linked to an unknown quality gate '%s'", id, condition.getQualityGateId()); wsSupport.checkCanEdit(qualityGateDto); QualityGateConditionDto updatedCondition = qualityGateConditionsUpdater.updateCondition(dbSession, condition, metric, operator, error); UpdateConditionResponse.Builder updateConditionResponse = UpdateConditionResponse.newBuilder() .setId(updatedCondition.getId()) .setMetric(updatedCondition.getMetricKey()) .setError(updatedCondition.getErrorThreshold()) .setOp(updatedCondition.getOperator()); writeProtobuf(updateConditionResponse.build(), request, response); dbSession.commit(); } } }
public QualityGateConditionDto createCondition(DbSession dbSession, QualityGateDto qualityGate, String metricKey, String operator, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period) { MetricDto metric = getNonNullMetric(dbSession, metricKey); validateCondition(metric, operator, warningThreshold, errorThreshold, period); checkConditionDoesNotAlreadyExistOnSameMetricAndPeriod(getConditions(dbSession, qualityGate.getId(), null), metric, period); QualityGateConditionDto newCondition = new QualityGateConditionDto().setQualityGateId(qualityGate.getId()) .setMetricId(metric.getId()).setMetricKey(metric.getKey()) .setOperator(operator) .setWarningThreshold(warningThreshold) .setErrorThreshold(errorThreshold) .setPeriod(period); dbClient.gateConditionDao().insert(newCondition, dbSession); return newCondition; }
private static void validateMetric(MetricDto metric, List<String> errors) { check(isAlertable(metric), errors, "Metric '%s' cannot be used to define a condition.", metric.getKey()); }
private static void checkPeriod(MetricDto metric, @Nullable Integer period, List<String> errors) { if (period == null) { check(!metric.getKey().startsWith("new_"), errors, "A period must be selected for differential metrics."); } else { check(period == 1, errors, "The only valid quality gate period is 1, the leak period."); } }
private void updateQualityConditionsIfRequired(DbSession dbSession, QualityGateDto builtin) { Map<Long, String> idToKeyMetric = dbClient.metricDao().selectAll(dbSession).stream() .collect(toMap(metricDto -> metricDto.getId().longValue(), MetricDto::getKey)); List<QualityGateCondition> qualityGateConditions = qualityGateConditionDao.selectForQualityGate(dbSession, builtin.getId()) .stream() .map(dto -> QualityGateCondition.from(dto, idToKeyMetric)) .collect(MoreCollectors.toList()); // Find all conditions that are not present in QUALITY_GATE_CONDITIONS // Those conditions must be deleted List<QualityGateCondition> qgConditionsToBeDeleted = new ArrayList<>(qualityGateConditions); qgConditionsToBeDeleted.removeAll(QUALITY_GATE_CONDITIONS); qgConditionsToBeDeleted .forEach(qgc -> qualityGateConditionDao.delete(qgc.toQualityGateDto(builtin.getId()), dbSession)); // Find all conditions that are not present in qualityGateConditions // Those conditions must be created List<QualityGateCondition> qgConditionsToBeCreated = new ArrayList<>(QUALITY_GATE_CONDITIONS); qgConditionsToBeCreated.removeAll(qualityGateConditions); qgConditionsToBeCreated .forEach(qgc -> qualityGateConditionsUpdater.createCondition(dbSession, builtin, qgc.getMetricKey(), qgc.getOperator(), qgc.getErrorThreshold())); if (!qgConditionsToBeCreated.isEmpty() || !qgConditionsToBeDeleted.isEmpty()) { LOGGER.info("Built-in quality gate's conditions of [{}] has been updated", BUILTIN_QUALITY_GATE_NAME); } }
@Test public void update_condition() { MetricDto metric = insertMetric(PERCENT); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric, c -> c.setOperator("LT").setErrorThreshold("80")); QualityGateConditionDto result = underTest.updateCondition(db.getSession(), condition, metric.getKey(), "LT", "80"); verifyCondition(result, qualityGate, metric, "LT", "80"); }
private static void checkRatingMetric(MetricDto metric, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period, List<String> errors) { if (!metric.getValueType().equals(RATING.name())) { return; } if (!isCoreRatingMetric(metric.getKey())) { errors.add(format("The metric '%s' cannot be used", metric.getShortName())); } if (period != null && !metric.getKey().startsWith("new_")) { errors.add(format("The metric '%s' cannot be used on the leak period", metric.getShortName())); } if (!isValidRating(warningThreshold)) { addInvalidRatingError(warningThreshold, errors); return; } if (!isValidRating(errorThreshold)) { addInvalidRatingError(errorThreshold, errors); return; } checkRatingGreaterThanOperator(warningThreshold, errors); checkRatingGreaterThanOperator(errorThreshold, errors); }