From ea3750d4e6207aba424ca9ec62da9d7d365cd6ec Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Thu, 20 Nov 2025 17:41:53 +0000 Subject: [PATCH] Regenerate client from commit 2aab4b8 of spec repo --- .generator/schemas/v1/openapi.yaml | 62 ++++- .../CreateSLO_512760759.java | 76 ++++++ .../client/v1/model/SLOCountCondition.java | 222 ++++++++++++++++++ .../api/client/v1/model/SLOCountSpec.java | 92 ++++++++ .../api/client/v1/model/SLOResponseData.java | 40 +--- .../api/client/v1/model/SLOSliSpec.java | 71 +++++- .../v1/model/ServiceLevelObjective.java | 8 +- .../v1/model/ServiceLevelObjectiveQuery.java | 6 +- .../model/ServiceLevelObjectiveRequest.java | 8 +- .../v1/api/service_level_objectives.feature | 26 ++ 10 files changed, 555 insertions(+), 56 deletions(-) create mode 100644 examples/v1/service-level-objectives/CreateSLO_512760759.java create mode 100644 src/main/java/com/datadog/api/client/v1/model/SLOCountCondition.java create mode 100644 src/main/java/com/datadog/api/client/v1/model/SLOCountSpec.java diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index e4c94965900..c132893290d 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -11409,6 +11409,60 @@ components: example: UTC type: string type: object + SLOCountCondition: + description: 'A count-based SLI specification, composed of three parts: the + good events formula, the total events formula, + + and the involved queries.' + example: + good_events_formula: query1 - query2 + queries: + - data_source: metrics + name: query1 + query: sum:trace.servlet.request.success{*} by {env}.as_count() + - data_source: metrics + name: query2 + query: sum:trace.servlet.request.hits{*} by {env}.as_count() + total_events_formula: query2 + properties: + good_events_formula: + $ref: '#/components/schemas/SLOFormula' + queries: + example: + - data_source: metrics + name: query1 + query: sum:trace.servlet.request.hits{*} by {env}.as_count() + items: + $ref: '#/components/schemas/SLODataSourceQueryDefinition' + minItems: 1 + type: array + total_events_formula: + $ref: '#/components/schemas/SLOFormula' + required: + - good_events_formula + - total_events_formula + - queries + type: object + SLOCountSpec: + additionalProperties: false + description: A count-based SLI specification. + example: + count: + good_events_formula: query1 - query2 + queries: + - data_source: metrics + name: query1 + query: sum:trace.servlet.request.success{*} by {env}.as_count() + - data_source: metrics + name: query2 + query: sum:trace.servlet.request.hits{*} by {env}.as_count() + total_events_formula: query2 + properties: + count: + $ref: '#/components/schemas/SLOCountCondition' + required: + - count + type: object SLOCreator: description: The creator of the SLO nullable: true @@ -12295,8 +12349,6 @@ components: type: array timeframe: $ref: '#/components/schemas/SLOTimeframe' - type: - $ref: '#/components/schemas/SLOType' warning_threshold: description: 'The optional warning threshold such that when the service level indicator is @@ -12314,9 +12366,10 @@ components: type: object SLOSliSpec: description: A generic SLI specification. This is currently used for time-slice - SLOs only. + and count-based SLOs only. oneOf: - $ref: '#/components/schemas/SLOTimeSliceSpec' + - $ref: '#/components/schemas/SLOCountSpec' SLOState: description: State of the SLO. enum: @@ -13468,8 +13521,7 @@ components: - type type: object ServiceLevelObjectiveQuery: - description: 'A metric-based SLO. **Required if type is `metric`**. Note that - Datadog only allows the sum by aggregator + description: 'A metric-based SLO. Note that Datadog only allows the sum by aggregator to be used because this will sum up all request counts instead of averaging them, or taking the max or diff --git a/examples/v1/service-level-objectives/CreateSLO_512760759.java b/examples/v1/service-level-objectives/CreateSLO_512760759.java new file mode 100644 index 00000000000..8e1adb177d1 --- /dev/null +++ b/examples/v1/service-level-objectives/CreateSLO_512760759.java @@ -0,0 +1,76 @@ +// Create a new metric SLO object using sli_specification returns "OK" response + +import com.datadog.api.client.ApiClient; +import com.datadog.api.client.ApiException; +import com.datadog.api.client.v1.api.ServiceLevelObjectivesApi; +import com.datadog.api.client.v1.model.FormulaAndFunctionMetricDataSource; +import com.datadog.api.client.v1.model.FormulaAndFunctionMetricQueryDefinition; +import com.datadog.api.client.v1.model.SLOCountCondition; +import com.datadog.api.client.v1.model.SLOCountSpec; +import com.datadog.api.client.v1.model.SLODataSourceQueryDefinition; +import com.datadog.api.client.v1.model.SLOFormula; +import com.datadog.api.client.v1.model.SLOListResponse; +import com.datadog.api.client.v1.model.SLOSliSpec; +import com.datadog.api.client.v1.model.SLOThreshold; +import com.datadog.api.client.v1.model.SLOTimeframe; +import com.datadog.api.client.v1.model.SLOType; +import com.datadog.api.client.v1.model.ServiceLevelObjectiveRequest; +import java.util.Arrays; +import java.util.Collections; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = ApiClient.getDefaultApiClient(); + ServiceLevelObjectivesApi apiInstance = new ServiceLevelObjectivesApi(defaultClient); + + ServiceLevelObjectiveRequest body = + new ServiceLevelObjectiveRequest() + .type(SLOType.METRIC) + .description("Metric SLO using sli_specification") + .name("Example-Service-Level-Objective") + .sliSpecification( + new SLOSliSpec( + new SLOCountSpec() + .count( + new SLOCountCondition() + .goodEventsFormula(new SLOFormula().formula("query1")) + .totalEventsFormula(new SLOFormula().formula("query2")) + .queries( + Arrays.asList( + new SLODataSourceQueryDefinition( + new FormulaAndFunctionMetricQueryDefinition() + .dataSource( + FormulaAndFunctionMetricDataSource.METRICS) + .name("query1") + .query("sum:httpservice.success{*}.as_count()")), + new SLODataSourceQueryDefinition( + new FormulaAndFunctionMetricQueryDefinition() + .dataSource( + FormulaAndFunctionMetricDataSource.METRICS) + .name("query2") + .query("sum:httpservice.hits{*}.as_count()"))))))) + .tags(Arrays.asList("env:prod", "type:count")) + .thresholds( + Collections.singletonList( + new SLOThreshold() + .target(99.0) + .targetDisplay("99.0") + .timeframe(SLOTimeframe.SEVEN_DAYS) + .warning(98.0) + .warningDisplay("98.0"))) + .timeframe(SLOTimeframe.SEVEN_DAYS) + .targetThreshold(99.0) + .warningThreshold(98.0); + + try { + SLOListResponse result = apiInstance.createSLO(body); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling ServiceLevelObjectivesApi#createSLO"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/SLOCountCondition.java b/src/main/java/com/datadog/api/client/v1/model/SLOCountCondition.java new file mode 100644 index 00000000000..af6e6980078 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/SLOCountCondition.java @@ -0,0 +1,222 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v1.model; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * A count-based SLI specification, composed of three parts: the good events formula, the total + * events formula, and the involved queries. + */ +@JsonPropertyOrder({ + SLOCountCondition.JSON_PROPERTY_GOOD_EVENTS_FORMULA, + SLOCountCondition.JSON_PROPERTY_QUERIES, + SLOCountCondition.JSON_PROPERTY_TOTAL_EVENTS_FORMULA +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class SLOCountCondition { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_GOOD_EVENTS_FORMULA = "good_events_formula"; + private SLOFormula goodEventsFormula; + + public static final String JSON_PROPERTY_QUERIES = "queries"; + private List queries = new ArrayList<>(); + + public static final String JSON_PROPERTY_TOTAL_EVENTS_FORMULA = "total_events_formula"; + private SLOFormula totalEventsFormula; + + public SLOCountCondition() {} + + @JsonCreator + public SLOCountCondition( + @JsonProperty(required = true, value = JSON_PROPERTY_GOOD_EVENTS_FORMULA) + SLOFormula goodEventsFormula, + @JsonProperty(required = true, value = JSON_PROPERTY_QUERIES) + List queries, + @JsonProperty(required = true, value = JSON_PROPERTY_TOTAL_EVENTS_FORMULA) + SLOFormula totalEventsFormula) { + this.goodEventsFormula = goodEventsFormula; + this.unparsed |= goodEventsFormula.unparsed; + this.queries = queries; + this.totalEventsFormula = totalEventsFormula; + this.unparsed |= totalEventsFormula.unparsed; + } + + public SLOCountCondition goodEventsFormula(SLOFormula goodEventsFormula) { + this.goodEventsFormula = goodEventsFormula; + this.unparsed |= goodEventsFormula.unparsed; + return this; + } + + /** + * A formula that specifies how to combine the results of multiple queries. + * + * @return goodEventsFormula + */ + @JsonProperty(JSON_PROPERTY_GOOD_EVENTS_FORMULA) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public SLOFormula getGoodEventsFormula() { + return goodEventsFormula; + } + + public void setGoodEventsFormula(SLOFormula goodEventsFormula) { + this.goodEventsFormula = goodEventsFormula; + } + + public SLOCountCondition queries(List queries) { + this.queries = queries; + for (SLODataSourceQueryDefinition item : queries) { + this.unparsed |= item.unparsed; + } + return this; + } + + public SLOCountCondition addQueriesItem(SLODataSourceQueryDefinition queriesItem) { + this.queries.add(queriesItem); + this.unparsed |= queriesItem.unparsed; + return this; + } + + /** + * Getqueries + * + * @return queries + */ + @JsonProperty(JSON_PROPERTY_QUERIES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getQueries() { + return queries; + } + + public void setQueries(List queries) { + this.queries = queries; + } + + public SLOCountCondition totalEventsFormula(SLOFormula totalEventsFormula) { + this.totalEventsFormula = totalEventsFormula; + this.unparsed |= totalEventsFormula.unparsed; + return this; + } + + /** + * A formula that specifies how to combine the results of multiple queries. + * + * @return totalEventsFormula + */ + @JsonProperty(JSON_PROPERTY_TOTAL_EVENTS_FORMULA) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public SLOFormula getTotalEventsFormula() { + return totalEventsFormula; + } + + public void setTotalEventsFormula(SLOFormula totalEventsFormula) { + this.totalEventsFormula = totalEventsFormula; + } + + /** + * A container for additional, undeclared properties. This is a holder for any undeclared + * properties as specified with the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. If the property + * does not already exist, create it otherwise replace it. + * + * @param key The arbitrary key to set + * @param value The associated value + * @return SLOCountCondition + */ + @JsonAnySetter + public SLOCountCondition putAdditionalProperty(String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) property. + * + * @return The additional properties + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * + * @param key The arbitrary key to get + * @return The specific additional property for the given key + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + /** Return true if this SLOCountCondition object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SLOCountCondition sloCountCondition = (SLOCountCondition) o; + return Objects.equals(this.goodEventsFormula, sloCountCondition.goodEventsFormula) + && Objects.equals(this.queries, sloCountCondition.queries) + && Objects.equals(this.totalEventsFormula, sloCountCondition.totalEventsFormula) + && Objects.equals(this.additionalProperties, sloCountCondition.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(goodEventsFormula, queries, totalEventsFormula, additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SLOCountCondition {\n"); + sb.append(" goodEventsFormula: ").append(toIndentedString(goodEventsFormula)).append("\n"); + sb.append(" queries: ").append(toIndentedString(queries)).append("\n"); + sb.append(" totalEventsFormula: ").append(toIndentedString(totalEventsFormula)).append("\n"); + sb.append(" additionalProperties: ") + .append(toIndentedString(additionalProperties)) + .append("\n"); + sb.append('}'); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/SLOCountSpec.java b/src/main/java/com/datadog/api/client/v1/model/SLOCountSpec.java new file mode 100644 index 00000000000..76957b9f793 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/SLOCountSpec.java @@ -0,0 +1,92 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v1.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.Objects; + +/** A count-based SLI specification. */ +@JsonPropertyOrder({SLOCountSpec.JSON_PROPERTY_COUNT}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class SLOCountSpec { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_COUNT = "count"; + private SLOCountCondition count; + + public SLOCountSpec() {} + + @JsonCreator + public SLOCountSpec( + @JsonProperty(required = true, value = JSON_PROPERTY_COUNT) SLOCountCondition count) { + this.count = count; + this.unparsed |= count.unparsed; + } + + public SLOCountSpec count(SLOCountCondition count) { + this.count = count; + this.unparsed |= count.unparsed; + return this; + } + + /** + * A count-based SLI specification, composed of three parts: the good events formula, the total + * events formula, and the involved queries. + * + * @return count + */ + @JsonProperty(JSON_PROPERTY_COUNT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public SLOCountCondition getCount() { + return count; + } + + public void setCount(SLOCountCondition count) { + this.count = count; + } + + /** Return true if this SLOCountSpec object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SLOCountSpec sloCountSpec = (SLOCountSpec) o; + return Objects.equals(this.count, sloCountSpec.count); + } + + @Override + public int hashCode() { + return Objects.hash(count); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SLOCountSpec {\n"); + sb.append(" count: ").append(toIndentedString(count)).append("\n"); + sb.append('}'); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/SLOResponseData.java b/src/main/java/com/datadog/api/client/v1/model/SLOResponseData.java index e55f6a99d45..2c0578812e5 100644 --- a/src/main/java/com/datadog/api/client/v1/model/SLOResponseData.java +++ b/src/main/java/com/datadog/api/client/v1/model/SLOResponseData.java @@ -40,7 +40,6 @@ SLOResponseData.JSON_PROPERTY_TARGET_THRESHOLD, SLOResponseData.JSON_PROPERTY_THRESHOLDS, SLOResponseData.JSON_PROPERTY_TIMEFRAME, - SLOResponseData.JSON_PROPERTY_TYPE, SLOResponseData.JSON_PROPERTY_WARNING_THRESHOLD }) @jakarta.annotation.Generated( @@ -95,9 +94,6 @@ public class SLOResponseData { public static final String JSON_PROPERTY_TIMEFRAME = "timeframe"; private SLOTimeframe timeframe; - public static final String JSON_PROPERTY_TYPE = "type"; - private SLOType type; - public static final String JSON_PROPERTY_WARNING_THRESHOLD = "warning_threshold"; private Double warningThreshold; @@ -343,9 +339,9 @@ public SLOResponseData query(ServiceLevelObjectiveQuery query) { } /** - * A metric-based SLO. Required if type is metric. Note that Datadog - * only allows the sum by aggregator to be used because this will sum up all request counts - * instead of averaging them, or taking the max or min of all of those requests. + * A metric-based SLO. Note that Datadog only allows the sum by aggregator to be used because this + * will sum up all request counts instead of averaging them, or taking the max or min of all of + * those requests. * * @return query */ @@ -367,7 +363,7 @@ public SLOResponseData sliSpecification(SLOSliSpec sliSpecification) { } /** - * A generic SLI specification. This is currently used for time-slice SLOs only. + * A generic SLI specification. This is currently used for time-slice and count-based SLOs only. * * @return sliSpecification */ @@ -493,31 +489,6 @@ public void setTimeframe(SLOTimeframe timeframe) { this.timeframe = timeframe; } - public SLOResponseData type(SLOType type) { - this.type = type; - this.unparsed |= !type.isValid(); - return this; - } - - /** - * The type of the service level objective. - * - * @return type - */ - @jakarta.annotation.Nullable - @JsonProperty(JSON_PROPERTY_TYPE) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public SLOType getType() { - return type; - } - - public void setType(SLOType type) { - if (!type.isValid()) { - this.unparsed = true; - } - this.type = type; - } - public SLOResponseData warningThreshold(Double warningThreshold) { this.warningThreshold = warningThreshold; return this; @@ -613,7 +584,6 @@ public boolean equals(Object o) { && Objects.equals(this.targetThreshold, sloResponseData.targetThreshold) && Objects.equals(this.thresholds, sloResponseData.thresholds) && Objects.equals(this.timeframe, sloResponseData.timeframe) - && Objects.equals(this.type, sloResponseData.type) && Objects.equals(this.warningThreshold, sloResponseData.warningThreshold) && Objects.equals(this.additionalProperties, sloResponseData.additionalProperties); } @@ -637,7 +607,6 @@ public int hashCode() { targetThreshold, thresholds, timeframe, - type, warningThreshold, additionalProperties); } @@ -662,7 +631,6 @@ public String toString() { sb.append(" targetThreshold: ").append(toIndentedString(targetThreshold)).append("\n"); sb.append(" thresholds: ").append(toIndentedString(thresholds)).append("\n"); sb.append(" timeframe: ").append(toIndentedString(timeframe)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); sb.append(" warningThreshold: ").append(toIndentedString(warningThreshold)).append("\n"); sb.append(" additionalProperties: ") .append(toIndentedString(additionalProperties)) diff --git a/src/main/java/com/datadog/api/client/v1/model/SLOSliSpec.java b/src/main/java/com/datadog/api/client/v1/model/SLOSliSpec.java index 36a3066f9f6..c45083515b6 100644 --- a/src/main/java/com/datadog/api/client/v1/model/SLOSliSpec.java +++ b/src/main/java/com/datadog/api/client/v1/model/SLOSliSpec.java @@ -121,6 +121,48 @@ public SLOSliSpec deserialize(JsonParser jp, DeserializationContext ctxt) log.log(Level.FINER, "Input data does not match schema 'SLOTimeSliceSpec'", e); } + // deserialize SLOCountSpec + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SLOCountSpec.class.equals(Integer.class) + || SLOCountSpec.class.equals(Long.class) + || SLOCountSpec.class.equals(Float.class) + || SLOCountSpec.class.equals(Double.class) + || SLOCountSpec.class.equals(Boolean.class) + || SLOCountSpec.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SLOCountSpec.class.equals(Integer.class) || SLOCountSpec.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SLOCountSpec.class.equals(Float.class) || SLOCountSpec.class.equals(Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (SLOCountSpec.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SLOCountSpec.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = tree.traverse(jp.getCodec()).readValueAs(SLOCountSpec.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + if (!((SLOCountSpec) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log(Level.FINER, "Input data matches schema 'SLOCountSpec'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'SLOCountSpec'", e); + } + SLOSliSpec ret = new SLOSliSpec(); if (match == 1) { ret.setActualInstance(deserialized); @@ -154,8 +196,14 @@ public SLOSliSpec(SLOTimeSliceSpec o) { setActualInstance(o); } + public SLOSliSpec(SLOCountSpec o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + static { schemas.put("SLOTimeSliceSpec", new GenericType() {}); + schemas.put("SLOCountSpec", new GenericType() {}); JSON.registerDescendants(SLOSliSpec.class, Collections.unmodifiableMap(schemas)); } @@ -166,7 +214,7 @@ public Map getSchemas() { /** * Set the instance that matches the oneOf child schema, check the instance parameter is valid - * against the oneOf child schemas: SLOTimeSliceSpec + * against the oneOf child schemas: SLOTimeSliceSpec, SLOCountSpec * *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a * composed schema (allOf, anyOf, oneOf). @@ -177,18 +225,22 @@ public void setActualInstance(Object instance) { super.setActualInstance(instance); return; } + if (JSON.isInstanceOf(SLOCountSpec.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } if (JSON.isInstanceOf(UnparsedObject.class, instance, new HashSet>())) { super.setActualInstance(instance); return; } - throw new RuntimeException("Invalid instance type. Must be SLOTimeSliceSpec"); + throw new RuntimeException("Invalid instance type. Must be SLOTimeSliceSpec, SLOCountSpec"); } /** - * Get the actual instance, which can be the following: SLOTimeSliceSpec + * Get the actual instance, which can be the following: SLOTimeSliceSpec, SLOCountSpec * - * @return The actual instance (SLOTimeSliceSpec) + * @return The actual instance (SLOTimeSliceSpec, SLOCountSpec) */ @Override public Object getActualInstance() { @@ -205,4 +257,15 @@ public Object getActualInstance() { public SLOTimeSliceSpec getSLOTimeSliceSpec() throws ClassCastException { return (SLOTimeSliceSpec) super.getActualInstance(); } + + /** + * Get the actual instance of `SLOCountSpec`. If the actual instance is not `SLOCountSpec`, the + * ClassCastException will be thrown. + * + * @return The actual instance of `SLOCountSpec` + * @throws ClassCastException if the instance is not `SLOCountSpec` + */ + public SLOCountSpec getSLOCountSpec() throws ClassCastException { + return (SLOCountSpec) super.getActualInstance(); + } } diff --git a/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjective.java b/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjective.java index a0e4f9b0371..5b4df5a3c43 100644 --- a/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjective.java +++ b/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjective.java @@ -324,9 +324,9 @@ public ServiceLevelObjective query(ServiceLevelObjectiveQuery query) { } /** - * A metric-based SLO. Required if type is metric. Note that Datadog - * only allows the sum by aggregator to be used because this will sum up all request counts - * instead of averaging them, or taking the max or min of all of those requests. + * A metric-based SLO. Note that Datadog only allows the sum by aggregator to be used because this + * will sum up all request counts instead of averaging them, or taking the max or min of all of + * those requests. * * @return query */ @@ -348,7 +348,7 @@ public ServiceLevelObjective sliSpecification(SLOSliSpec sliSpecification) { } /** - * A generic SLI specification. This is currently used for time-slice SLOs only. + * A generic SLI specification. This is currently used for time-slice and count-based SLOs only. * * @return sliSpecification */ diff --git a/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveQuery.java b/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveQuery.java index aee83319b41..091390e0a40 100644 --- a/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveQuery.java +++ b/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveQuery.java @@ -18,9 +18,9 @@ import java.util.Objects; /** - * A metric-based SLO. Required if type is metric. Note that Datadog - * only allows the sum by aggregator to be used because this will sum up all request counts instead - * of averaging them, or taking the max or min of all of those requests. + * A metric-based SLO. Note that Datadog only allows the sum by aggregator to be used because this + * will sum up all request counts instead of averaging them, or taking the max or min of all of + * those requests. */ @JsonPropertyOrder({ ServiceLevelObjectiveQuery.JSON_PROPERTY_DENOMINATOR, diff --git a/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveRequest.java b/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveRequest.java index dfb2e482c73..640ea261a35 100644 --- a/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveRequest.java +++ b/src/main/java/com/datadog/api/client/v1/model/ServiceLevelObjectiveRequest.java @@ -217,9 +217,9 @@ public ServiceLevelObjectiveRequest query(ServiceLevelObjectiveQuery query) { } /** - * A metric-based SLO. Required if type is metric. Note that Datadog - * only allows the sum by aggregator to be used because this will sum up all request counts - * instead of averaging them, or taking the max or min of all of those requests. + * A metric-based SLO. Note that Datadog only allows the sum by aggregator to be used because this + * will sum up all request counts instead of averaging them, or taking the max or min of all of + * those requests. * * @return query */ @@ -241,7 +241,7 @@ public ServiceLevelObjectiveRequest sliSpecification(SLOSliSpec sliSpecification } /** - * A generic SLI specification. This is currently used for time-slice SLOs only. + * A generic SLI specification. This is currently used for time-slice and count-based SLOs only. * * @return sliSpecification */ diff --git a/src/test/resources/com/datadog/api/client/v1/api/service_level_objectives.feature b/src/test/resources/com/datadog/api/client/v1/api/service_level_objectives.feature index c5534618a73..3fba149b2d3 100644 --- a/src/test/resources/com/datadog/api/client/v1/api/service_level_objectives.feature +++ b/src/test/resources/com/datadog/api/client/v1/api/service_level_objectives.feature @@ -48,6 +48,30 @@ Feature: Service Level Objectives When the request is sent Then the response status is 200 OK + @team:DataDog/slo-app + Scenario: Create a metric SLO with both sli_specification and query returns "Bad Request" response + Given new "CreateSLO" request + And body with value {"type":"metric","description":"Invalid SLO with both sli_specification and query","name":"{{ unique }}","sli_specification":{"count":{"good_events_formula":{"formula":"query1"},"total_events_formula":{"formula":"query2"},"queries":[{"data_source":"metrics","name":"query1","query":"sum:httpservice.success{*}.as_count()"},{"data_source":"metrics","name":"query2","query":"sum:httpservice.hits{*}.as_count()"}]}},"query":{"numerator":"sum:httpservice.success{*}.as_count()","denominator":"sum:httpservice.hits{*}.as_count()"},"tags":["env:prod"],"thresholds":[{"target":99.0,"target_display":"99.0","timeframe":"7d","warning":98,"warning_display":"98.0"}],"timeframe":"7d","target_threshold":99.0,"warning_threshold":98} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/slo-app + Scenario: Create a new metric SLO object using sli_specification returns "OK" response + Given new "CreateSLO" request + And body with value {"type":"metric","description":"Metric SLO using sli_specification","name":"{{ unique }}","sli_specification":{"count":{"good_events_formula":{"formula":"query1"},"total_events_formula":{"formula":"query2"},"queries":[{"data_source":"metrics","name":"query1","query":"sum:httpservice.success{*}.as_count()"},{"data_source":"metrics","name":"query2","query":"sum:httpservice.hits{*}.as_count()"}]}},"tags":["env:prod","type:count"],"thresholds":[{"target":99.0,"target_display":"99.0","timeframe":"7d","warning":98,"warning_display":"98.0"}],"timeframe":"7d","target_threshold":99.0,"warning_threshold":98} + When the request is sent + Then the response status is 200 OK + And the response "data[0].timeframe" is equal to "7d" + And the response "data[0].target_threshold" is equal to 99.0 + And the response "data[0].warning_threshold" is equal to 98.0 + And the response "data[0]" has field "sli_specification" + And the response "data[0].sli_specification" has field "count" + And the response "data[0].sli_specification.count" has field "good_events_formula" + And the response "data[0].sli_specification.count" has field "total_events_formula" + And the response "data[0].sli_specification.count" has field "queries" + And the response "data[0].sli_specification.count.queries" has length 2 + And the response "data[0]" does not have field "query" + @team:DataDog/slo-app Scenario: Create a time-slice SLO object returns "OK" response Given new "CreateSLO" request @@ -74,6 +98,8 @@ Feature: Service Level Objectives And the response "data[0].timeframe" is equal to "7d" And the response "data[0].target_threshold" is equal to 97.0 And the response "data[0].warning_threshold" is equal to 98.0 + And the response "data[0]" has field "query" + And the response "data[0]" does not have field "sli_specification" @generated @skip @team:DataDog/slo-app Scenario: Delete an SLO returns "Conflict" response