From a11a2ab2bff7b83d9ed2dce56ffae59edbcd82a8 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Fri, 13 Mar 2026 03:53:46 +0000 Subject: [PATCH] Regenerate client from commit 53a6366 of spec repo --- .generator/schemas/v1/openapi.yaml | 64 ++- .../CreateSLO_512760759.java | 37 +- .../CreateSLO_707861409.java | 79 ++++ .../client/v1/model/SLOCountDefinition.java | 415 +++++++++++------- ...LOCountDefinitionWithBadEventsFormula.java | 170 +++++++ ...CountDefinitionWithTotalEventsFormula.java | 171 ++++++++ .../api/client/v1/model/SLOCountSpec.java | 3 +- ..._events_formula_returns_OK_response.freeze | 1 + ...ad_events_formula_returns_OK_response.json | 58 +++ .../v1/api/service_level_objectives.feature | 15 +- 10 files changed, 814 insertions(+), 199 deletions(-) create mode 100644 examples/v1/service-level-objectives/CreateSLO_707861409.java create mode 100644 src/main/java/com/datadog/api/client/v1/model/SLOCountDefinitionWithBadEventsFormula.java create mode 100644 src/main/java/com/datadog/api/client/v1/model/SLOCountDefinitionWithTotalEventsFormula.java create mode 100644 src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.freeze create mode 100644 src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.json diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index daa9d89fc34..ea9665ada3d 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -12338,33 +12338,73 @@ components: type: object SLOCountDefinition: description: 'A count-based (metric) SLI specification, composed of three parts: - the good events formula, the total events formula, + the good events formula, - and the underlying queries.' + the bad or total events formula, and the underlying queries. + + Exactly one of `total_events_formula` or `bad_events_formula` must be provided.' example: - good_events_formula: query1 - query2 + bad_events_formula: query2 + good_events_formula: query1 queries: - data_source: metrics name: query1 - query: sum:trace.servlet.request.hits{*} by {env}.as_count() + query: sum:trace.servlet.request.hits{!http.status_code:500} by {env}.as_count() - data_source: metrics name: query2 - query: sum:trace.servlet.request.errors{*} by {env}.as_count() - total_events_formula: query1 + query: sum:trace.servlet.request.hits{http.status_code:500} by {env}.as_count() + oneOf: + - $ref: '#/components/schemas/SLOCountDefinitionWithTotalEventsFormula' + - $ref: '#/components/schemas/SLOCountDefinitionWithBadEventsFormula' + SLOCountDefinitionWithBadEventsFormula: + additionalProperties: false properties: + bad_events_formula: + $ref: '#/components/schemas/SLOFormula' + description: The bad events formula (recommended). Total events queries + can be defined using the `total_events_formula` field as an alternative. + Only one of `total_events_formula` or `bad_events_formula` must be provided. good_events_formula: $ref: '#/components/schemas/SLOFormula' queries: example: - data_source: metrics name: query1 - query: sum:trace.servlet.request.hits{*} by {env}.as_count() + query: sum:trace.servlet.request.hits{!http.status_code:500} by {env}.as_count() + - data_source: metrics + name: query2 + query: sum:trace.servlet.request.hits{http.status_code:500} by {env}.as_count() + items: + $ref: '#/components/schemas/SLODataSourceQueryDefinition' + minItems: 1 + type: array + required: + - good_events_formula + - bad_events_formula + - queries + type: object + SLOCountDefinitionWithTotalEventsFormula: + additionalProperties: false + properties: + good_events_formula: + $ref: '#/components/schemas/SLOFormula' + queries: + example: + - data_source: metrics + name: query1 + query: sum:trace.servlet.request.hits{!http.status_code:500} by {env}.as_count() + - data_source: metrics + name: query2 + query: sum:trace.servlet.request.hits{http.status_code:500} by {env}.as_count() items: $ref: '#/components/schemas/SLODataSourceQueryDefinition' minItems: 1 type: array total_events_formula: $ref: '#/components/schemas/SLOFormula' + description: The total events formula. Bad events queries can be defined + using the `bad_events_formula` field as an alternative. Only one of `total_events_formula` + or `bad_events_formula` must be provided. required: - good_events_formula - total_events_formula @@ -12375,15 +12415,15 @@ components: description: A metric SLI specification. example: count: - good_events_formula: query1 - query2 + bad_events_formula: query2 + good_events_formula: query1 queries: - data_source: metrics name: query1 - query: sum:trace.servlet.request.hits{*} by {env}.as_count() + query: sum:trace.servlet.request.hits{!http.status_code:500} by {env}.as_count() - data_source: metrics name: query2 - query: sum:trace.servlet.request.errors{*} by {env}.as_count() - total_events_formula: query1 + query: sum:trace.servlet.request.hits{http.status_code:500} by {env}.as_count() properties: count: $ref: '#/components/schemas/SLOCountDefinition' @@ -13519,7 +13559,7 @@ components: name: query1 query: sum:trace.servlet.request.hits{*} by {env}.as_count() - data_source: metrics - name: query1 + name: query2 query: sum:trace.servlet.request.errors{*} by {env}.as_count() threshold: 5 properties: diff --git a/examples/v1/service-level-objectives/CreateSLO_512760759.java b/examples/v1/service-level-objectives/CreateSLO_512760759.java index ccbd3e89353..f159dd21534 100644 --- a/examples/v1/service-level-objectives/CreateSLO_512760759.java +++ b/examples/v1/service-level-objectives/CreateSLO_512760759.java @@ -6,6 +6,7 @@ import com.datadog.api.client.v1.model.FormulaAndFunctionMetricDataSource; import com.datadog.api.client.v1.model.FormulaAndFunctionMetricQueryDefinition; import com.datadog.api.client.v1.model.SLOCountDefinition; +import com.datadog.api.client.v1.model.SLOCountDefinitionWithTotalEventsFormula; import com.datadog.api.client.v1.model.SLOCountSpec; import com.datadog.api.client.v1.model.SLODataSourceQueryDefinition; import com.datadog.api.client.v1.model.SLOFormula; @@ -32,23 +33,25 @@ public static void main(String[] args) { new SLOSliSpec( new SLOCountSpec() .count( - new SLOCountDefinition() - .goodEventsFormula(new SLOFormula().formula("query1 - query2")) - .totalEventsFormula(new SLOFormula().formula("query1")) - .queries( - Arrays.asList( - new SLODataSourceQueryDefinition( - new FormulaAndFunctionMetricQueryDefinition() - .dataSource( - FormulaAndFunctionMetricDataSource.METRICS) - .name("query1") - .query("sum:httpservice.hits{*}.as_count()")), - new SLODataSourceQueryDefinition( - new FormulaAndFunctionMetricQueryDefinition() - .dataSource( - FormulaAndFunctionMetricDataSource.METRICS) - .name("query2") - .query("sum:httpservice.errors{*}.as_count()"))))))) + new SLOCountDefinition( + new SLOCountDefinitionWithTotalEventsFormula() + .goodEventsFormula(new SLOFormula().formula("query1 - query2")) + .totalEventsFormula(new SLOFormula().formula("query1")) + .queries( + Arrays.asList( + new SLODataSourceQueryDefinition( + new FormulaAndFunctionMetricQueryDefinition() + .dataSource( + FormulaAndFunctionMetricDataSource.METRICS) + .name("query1") + .query("sum:httpservice.hits{*}.as_count()")), + new SLODataSourceQueryDefinition( + new FormulaAndFunctionMetricQueryDefinition() + .dataSource( + FormulaAndFunctionMetricDataSource.METRICS) + .name("query2") + .query( + "sum:httpservice.errors{*}.as_count()")))))))) .tags(Arrays.asList("env:prod", "type:count")) .thresholds( Collections.singletonList( diff --git a/examples/v1/service-level-objectives/CreateSLO_707861409.java b/examples/v1/service-level-objectives/CreateSLO_707861409.java new file mode 100644 index 00000000000..a3f25cc6918 --- /dev/null +++ b/examples/v1/service-level-objectives/CreateSLO_707861409.java @@ -0,0 +1,79 @@ +// Create a new metric SLO object using bad events formula 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.SLOCountDefinition; +import com.datadog.api.client.v1.model.SLOCountDefinitionWithBadEventsFormula; +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 SLOCountDefinition( + new SLOCountDefinitionWithBadEventsFormula() + .goodEventsFormula(new SLOFormula().formula("query1 - query2")) + .badEventsFormula(new SLOFormula().formula("query2")) + .queries( + Arrays.asList( + new SLODataSourceQueryDefinition( + new FormulaAndFunctionMetricQueryDefinition() + .dataSource( + FormulaAndFunctionMetricDataSource.METRICS) + .name("query1") + .query("sum:httpservice.hits{*}.as_count()")), + new SLODataSourceQueryDefinition( + new FormulaAndFunctionMetricQueryDefinition() + .dataSource( + FormulaAndFunctionMetricDataSource.METRICS) + .name("query2") + .query( + "sum:httpservice.errors{*}.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(99.5) + .warningDisplay("99.5"))) + .timeframe(SLOTimeframe.SEVEN_DAYS) + .targetThreshold(99.0) + .warningThreshold(99.5); + + 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/SLOCountDefinition.java b/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinition.java index d63c83045ef..d6f78c3af74 100644 --- a/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinition.java +++ b/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinition.java @@ -6,217 +6,296 @@ 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.datadog.api.client.AbstractOpenApiSchema; +import com.datadog.api.client.JSON; +import com.datadog.api.client.UnparsedObject; 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 com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import jakarta.ws.rs.core.GenericType; +import java.io.IOException; +import java.util.Collections; import java.util.HashMap; -import java.util.List; +import java.util.HashSet; import java.util.Map; -import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; -/** - * A count-based (metric) SLI specification, composed of three parts: the good events formula, the - * total events formula, and the underlying queries. - */ -@JsonPropertyOrder({ - SLOCountDefinition.JSON_PROPERTY_GOOD_EVENTS_FORMULA, - SLOCountDefinition.JSON_PROPERTY_QUERIES, - SLOCountDefinition.JSON_PROPERTY_TOTAL_EVENTS_FORMULA -}) @jakarta.annotation.Generated( value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") -public class SLOCountDefinition { +@JsonDeserialize(using = SLOCountDefinition.SLOCountDefinitionDeserializer.class) +@JsonSerialize(using = SLOCountDefinition.SLOCountDefinitionSerializer.class) +public class SLOCountDefinition extends AbstractOpenApiSchema { + private static final Logger log = Logger.getLogger(SLOCountDefinition.class.getName()); + @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 SLOCountDefinition() {} - - @JsonCreator - public SLOCountDefinition( - @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 SLOCountDefinition goodEventsFormula(SLOFormula goodEventsFormula) { - this.goodEventsFormula = goodEventsFormula; - this.unparsed |= goodEventsFormula.unparsed; - return this; - } + public static class SLOCountDefinitionSerializer extends StdSerializer { + public SLOCountDefinitionSerializer(Class t) { + super(t); + } - /** - * 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 SLOCountDefinitionSerializer() { + this(null); + } - public void setGoodEventsFormula(SLOFormula goodEventsFormula) { - this.goodEventsFormula = goodEventsFormula; + @Override + public void serialize(SLOCountDefinition value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } } - public SLOCountDefinition queries(List queries) { - this.queries = queries; - for (SLODataSourceQueryDefinition item : queries) { - this.unparsed |= item.unparsed; + public static class SLOCountDefinitionDeserializer extends StdDeserializer { + public SLOCountDefinitionDeserializer() { + this(SLOCountDefinition.class); } - return this; - } - public SLOCountDefinition addQueriesItem(SLODataSourceQueryDefinition queriesItem) { - this.queries.add(queriesItem); - this.unparsed |= queriesItem.unparsed; - return this; - } + public SLOCountDefinitionDeserializer(Class vc) { + super(vc); + } - /** - * Getqueries - * - * @return queries - */ - @JsonProperty(JSON_PROPERTY_QUERIES) - @JsonInclude(value = JsonInclude.Include.ALWAYS) - public List getQueries() { - return queries; + @Override + public SLOCountDefinition deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode tree = jp.readValueAsTree(); + Object deserialized = null; + Object tmp = null; + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize SLOCountDefinitionWithTotalEventsFormula + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SLOCountDefinitionWithTotalEventsFormula.class.equals(Integer.class) + || SLOCountDefinitionWithTotalEventsFormula.class.equals(Long.class) + || SLOCountDefinitionWithTotalEventsFormula.class.equals(Float.class) + || SLOCountDefinitionWithTotalEventsFormula.class.equals(Double.class) + || SLOCountDefinitionWithTotalEventsFormula.class.equals(Boolean.class) + || SLOCountDefinitionWithTotalEventsFormula.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SLOCountDefinitionWithTotalEventsFormula.class.equals(Integer.class) + || SLOCountDefinitionWithTotalEventsFormula.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SLOCountDefinitionWithTotalEventsFormula.class.equals(Float.class) + || SLOCountDefinitionWithTotalEventsFormula.class.equals(Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (SLOCountDefinitionWithTotalEventsFormula.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SLOCountDefinitionWithTotalEventsFormula.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = + tree.traverse(jp.getCodec()) + .readValueAs(SLOCountDefinitionWithTotalEventsFormula.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 (!((SLOCountDefinitionWithTotalEventsFormula) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log( + Level.FINER, "Input data matches schema 'SLOCountDefinitionWithTotalEventsFormula'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log( + Level.FINER, + "Input data does not match schema 'SLOCountDefinitionWithTotalEventsFormula'", + e); + } + + // deserialize SLOCountDefinitionWithBadEventsFormula + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SLOCountDefinitionWithBadEventsFormula.class.equals(Integer.class) + || SLOCountDefinitionWithBadEventsFormula.class.equals(Long.class) + || SLOCountDefinitionWithBadEventsFormula.class.equals(Float.class) + || SLOCountDefinitionWithBadEventsFormula.class.equals(Double.class) + || SLOCountDefinitionWithBadEventsFormula.class.equals(Boolean.class) + || SLOCountDefinitionWithBadEventsFormula.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SLOCountDefinitionWithBadEventsFormula.class.equals(Integer.class) + || SLOCountDefinitionWithBadEventsFormula.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SLOCountDefinitionWithBadEventsFormula.class.equals(Float.class) + || SLOCountDefinitionWithBadEventsFormula.class.equals(Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (SLOCountDefinitionWithBadEventsFormula.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SLOCountDefinitionWithBadEventsFormula.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = + tree.traverse(jp.getCodec()) + .readValueAs(SLOCountDefinitionWithBadEventsFormula.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 (!((SLOCountDefinitionWithBadEventsFormula) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log( + Level.FINER, "Input data matches schema 'SLOCountDefinitionWithBadEventsFormula'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log( + Level.FINER, + "Input data does not match schema 'SLOCountDefinitionWithBadEventsFormula'", + e); + } + + SLOCountDefinition ret = new SLOCountDefinition(); + if (match == 1) { + ret.setActualInstance(deserialized); + } else { + Map res = + new ObjectMapper() + .readValue( + tree.traverse(jp.getCodec()).readValueAsTree().toString(), + new TypeReference>() {}); + ret.setActualInstance(new UnparsedObject(res)); + } + return ret; + } + + /** Handle deserialization of the 'null' value. */ + @Override + public SLOCountDefinition getNullValue(DeserializationContext ctxt) + throws JsonMappingException { + throw new JsonMappingException(ctxt.getParser(), "SLOCountDefinition cannot be null"); + } } - public void setQueries(List queries) { - this.queries = queries; + // store a list of schema names defined in oneOf + public static final Map schemas = new HashMap(); + + public SLOCountDefinition() { + super("oneOf", Boolean.FALSE); } - public SLOCountDefinition totalEventsFormula(SLOFormula totalEventsFormula) { - this.totalEventsFormula = totalEventsFormula; - this.unparsed |= totalEventsFormula.unparsed; - return this; + public SLOCountDefinition(SLOCountDefinitionWithTotalEventsFormula o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); } - /** - * 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 SLOCountDefinition(SLOCountDefinitionWithBadEventsFormula o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); } - public void setTotalEventsFormula(SLOFormula totalEventsFormula) { - this.totalEventsFormula = totalEventsFormula; + static { + schemas.put( + "SLOCountDefinitionWithTotalEventsFormula", + new GenericType() {}); + schemas.put( + "SLOCountDefinitionWithBadEventsFormula", + new GenericType() {}); + JSON.registerDescendants(SLOCountDefinition.class, Collections.unmodifiableMap(schemas)); } - /** - * 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; + @Override + public Map getSchemas() { + return SLOCountDefinition.schemas; + } /** - * Set the additional (undeclared) property with the specified name and value. If the property - * does not already exist, create it otherwise replace it. + * Set the instance that matches the oneOf child schema, check the instance parameter is valid + * against the oneOf child schemas: SLOCountDefinitionWithTotalEventsFormula, + * SLOCountDefinitionWithBadEventsFormula * - * @param key The arbitrary key to set - * @param value The associated value - * @return SLOCountDefinition + *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a + * composed schema (allOf, anyOf, oneOf). */ - @JsonAnySetter - public SLOCountDefinition putAdditionalProperty(String key, Object value) { - if (this.additionalProperties == null) { - this.additionalProperties = new HashMap(); + @Override + public void setActualInstance(Object instance) { + if (JSON.isInstanceOf( + SLOCountDefinitionWithTotalEventsFormula.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; } - this.additionalProperties.put(key, value); - return this; + if (JSON.isInstanceOf( + SLOCountDefinitionWithBadEventsFormula.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 SLOCountDefinitionWithTotalEventsFormula," + + " SLOCountDefinitionWithBadEventsFormula"); } /** - * Return the additional (undeclared) property. + * Get the actual instance, which can be the following: SLOCountDefinitionWithTotalEventsFormula, + * SLOCountDefinitionWithBadEventsFormula * - * @return The additional properties + * @return The actual instance (SLOCountDefinitionWithTotalEventsFormula, + * SLOCountDefinitionWithBadEventsFormula) */ - @JsonAnyGetter - public Map getAdditionalProperties() { - return additionalProperties; + @Override + public Object getActualInstance() { + return super.getActualInstance(); } /** - * Return the additional (undeclared) property with the specified name. + * Get the actual instance of `SLOCountDefinitionWithTotalEventsFormula`. If the actual instance + * is not `SLOCountDefinitionWithTotalEventsFormula`, the ClassCastException will be thrown. * - * @param key The arbitrary key to get - * @return The specific additional property for the given key + * @return The actual instance of `SLOCountDefinitionWithTotalEventsFormula` + * @throws ClassCastException if the instance is not `SLOCountDefinitionWithTotalEventsFormula` */ - public Object getAdditionalProperty(String key) { - if (this.additionalProperties == null) { - return null; - } - return this.additionalProperties.get(key); - } - - /** Return true if this SLOCountDefinition object is equal to o. */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SLOCountDefinition sloCountDefinition = (SLOCountDefinition) o; - return Objects.equals(this.goodEventsFormula, sloCountDefinition.goodEventsFormula) - && Objects.equals(this.queries, sloCountDefinition.queries) - && Objects.equals(this.totalEventsFormula, sloCountDefinition.totalEventsFormula) - && Objects.equals(this.additionalProperties, sloCountDefinition.additionalProperties); - } - - @Override - public int hashCode() { - return Objects.hash(goodEventsFormula, queries, totalEventsFormula, additionalProperties); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class SLOCountDefinition {\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(); + public SLOCountDefinitionWithTotalEventsFormula getSLOCountDefinitionWithTotalEventsFormula() + throws ClassCastException { + return (SLOCountDefinitionWithTotalEventsFormula) super.getActualInstance(); } /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). + * Get the actual instance of `SLOCountDefinitionWithBadEventsFormula`. If the actual instance is + * not `SLOCountDefinitionWithBadEventsFormula`, the ClassCastException will be thrown. + * + * @return The actual instance of `SLOCountDefinitionWithBadEventsFormula` + * @throws ClassCastException if the instance is not `SLOCountDefinitionWithBadEventsFormula` */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); + public SLOCountDefinitionWithBadEventsFormula getSLOCountDefinitionWithBadEventsFormula() + throws ClassCastException { + return (SLOCountDefinitionWithBadEventsFormula) super.getActualInstance(); } } diff --git a/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinitionWithBadEventsFormula.java b/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinitionWithBadEventsFormula.java new file mode 100644 index 00000000000..b4135b67a5b --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinitionWithBadEventsFormula.java @@ -0,0 +1,170 @@ +/* + * 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.ArrayList; +import java.util.List; +import java.util.Objects; + +/** */ +@JsonPropertyOrder({ + SLOCountDefinitionWithBadEventsFormula.JSON_PROPERTY_BAD_EVENTS_FORMULA, + SLOCountDefinitionWithBadEventsFormula.JSON_PROPERTY_GOOD_EVENTS_FORMULA, + SLOCountDefinitionWithBadEventsFormula.JSON_PROPERTY_QUERIES +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class SLOCountDefinitionWithBadEventsFormula { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_BAD_EVENTS_FORMULA = "bad_events_formula"; + private SLOFormula badEventsFormula; + + 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 SLOCountDefinitionWithBadEventsFormula() {} + + @JsonCreator + public SLOCountDefinitionWithBadEventsFormula( + @JsonProperty(required = true, value = JSON_PROPERTY_BAD_EVENTS_FORMULA) + SLOFormula badEventsFormula, + @JsonProperty(required = true, value = JSON_PROPERTY_GOOD_EVENTS_FORMULA) + SLOFormula goodEventsFormula, + @JsonProperty(required = true, value = JSON_PROPERTY_QUERIES) + List queries) { + this.badEventsFormula = badEventsFormula; + this.unparsed |= badEventsFormula.unparsed; + this.goodEventsFormula = goodEventsFormula; + this.unparsed |= goodEventsFormula.unparsed; + this.queries = queries; + } + + public SLOCountDefinitionWithBadEventsFormula badEventsFormula(SLOFormula badEventsFormula) { + this.badEventsFormula = badEventsFormula; + this.unparsed |= badEventsFormula.unparsed; + return this; + } + + /** + * A formula that specifies how to combine the results of multiple queries. + * + * @return badEventsFormula + */ + @JsonProperty(JSON_PROPERTY_BAD_EVENTS_FORMULA) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public SLOFormula getBadEventsFormula() { + return badEventsFormula; + } + + public void setBadEventsFormula(SLOFormula badEventsFormula) { + this.badEventsFormula = badEventsFormula; + } + + public SLOCountDefinitionWithBadEventsFormula 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 SLOCountDefinitionWithBadEventsFormula queries( + List queries) { + this.queries = queries; + for (SLODataSourceQueryDefinition item : queries) { + this.unparsed |= item.unparsed; + } + return this; + } + + public SLOCountDefinitionWithBadEventsFormula 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; + } + + /** Return true if this SLOCountDefinitionWithBadEventsFormula object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SLOCountDefinitionWithBadEventsFormula sloCountDefinitionWithBadEventsFormula = + (SLOCountDefinitionWithBadEventsFormula) o; + return Objects.equals( + this.badEventsFormula, sloCountDefinitionWithBadEventsFormula.badEventsFormula) + && Objects.equals( + this.goodEventsFormula, sloCountDefinitionWithBadEventsFormula.goodEventsFormula) + && Objects.equals(this.queries, sloCountDefinitionWithBadEventsFormula.queries); + } + + @Override + public int hashCode() { + return Objects.hash(badEventsFormula, goodEventsFormula, queries); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SLOCountDefinitionWithBadEventsFormula {\n"); + sb.append(" badEventsFormula: ").append(toIndentedString(badEventsFormula)).append("\n"); + sb.append(" goodEventsFormula: ").append(toIndentedString(goodEventsFormula)).append("\n"); + sb.append(" queries: ").append(toIndentedString(queries)).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/SLOCountDefinitionWithTotalEventsFormula.java b/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinitionWithTotalEventsFormula.java new file mode 100644 index 00000000000..95e2e4325e2 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/SLOCountDefinitionWithTotalEventsFormula.java @@ -0,0 +1,171 @@ +/* + * 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.ArrayList; +import java.util.List; +import java.util.Objects; + +/** */ +@JsonPropertyOrder({ + SLOCountDefinitionWithTotalEventsFormula.JSON_PROPERTY_GOOD_EVENTS_FORMULA, + SLOCountDefinitionWithTotalEventsFormula.JSON_PROPERTY_QUERIES, + SLOCountDefinitionWithTotalEventsFormula.JSON_PROPERTY_TOTAL_EVENTS_FORMULA +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class SLOCountDefinitionWithTotalEventsFormula { + @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 SLOCountDefinitionWithTotalEventsFormula() {} + + @JsonCreator + public SLOCountDefinitionWithTotalEventsFormula( + @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 SLOCountDefinitionWithTotalEventsFormula 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 SLOCountDefinitionWithTotalEventsFormula queries( + List queries) { + this.queries = queries; + for (SLODataSourceQueryDefinition item : queries) { + this.unparsed |= item.unparsed; + } + return this; + } + + public SLOCountDefinitionWithTotalEventsFormula 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 SLOCountDefinitionWithTotalEventsFormula 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; + } + + /** Return true if this SLOCountDefinitionWithTotalEventsFormula object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SLOCountDefinitionWithTotalEventsFormula sloCountDefinitionWithTotalEventsFormula = + (SLOCountDefinitionWithTotalEventsFormula) o; + return Objects.equals( + this.goodEventsFormula, sloCountDefinitionWithTotalEventsFormula.goodEventsFormula) + && Objects.equals(this.queries, sloCountDefinitionWithTotalEventsFormula.queries) + && Objects.equals( + this.totalEventsFormula, sloCountDefinitionWithTotalEventsFormula.totalEventsFormula); + } + + @Override + public int hashCode() { + return Objects.hash(goodEventsFormula, queries, totalEventsFormula); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SLOCountDefinitionWithTotalEventsFormula {\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('}'); + 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 index d11603840c5..b327e9a2dd5 100644 --- a/src/main/java/com/datadog/api/client/v1/model/SLOCountSpec.java +++ b/src/main/java/com/datadog/api/client/v1/model/SLOCountSpec.java @@ -39,7 +39,8 @@ public SLOCountSpec count(SLOCountDefinition count) { /** * A count-based (metric) SLI specification, composed of three parts: the good events formula, the - * total events formula, and the underlying queries. + * bad or total events formula, and the underlying queries. Exactly one of + * total_events_formula or bad_events_formula must be provided. * * @return count */ diff --git a/src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.freeze b/src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.freeze new file mode 100644 index 00000000000..b1ab9b09452 --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.freeze @@ -0,0 +1 @@ +2026-02-25T17:45:38.518Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.json b/src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.json new file mode 100644 index 00000000000..92a340d8d59 --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response.json @@ -0,0 +1,58 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"description\": \"Metric SLO using sli_specification\", \"name\": \"Test-Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response-1772041538\", \"sli_specification\": {\"count\": {\"bad_events_formula\": {\"formula\": \"query2\"}, \"good_events_formula\": {\"formula\": \"query1 - query2\"}, \"queries\": [{\"data_source\": \"metrics\", \"name\": \"query1\", \"query\": \"sum:httpservice.hits{*}.as_count()\"}, {\"data_source\": \"metrics\", \"name\": \"query2\", \"query\": \"sum:httpservice.errors{*}.as_count()\"}]}}, \"tags\": [\"env:prod\", \"type:count\"], \"target_threshold\": 99, \"thresholds\": [{\"target\": 99.0, \"target_display\": \"99.0\", \"timeframe\": \"7d\", \"warning\": 99.5, \"warning_display\": \"99.5\"}], \"timeframe\": \"7d\", \"type\": \"metric\", \"warning_threshold\": 99.5}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v1/slo", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"data\":[{\"id\":\"7309ff3752fd519f80f65a2ed3247dbb\",\"name\":\"Test-Create_a_new_metric_SLO_object_using_bad_events_formula_returns_OK_response-1772041538\",\"tags\":[\"env:prod\",\"type:count\"],\"monitor_tags\":[],\"thresholds\":[{\"timeframe\":\"7d\",\"target\":99.0,\"target_display\":\"99.\",\"warning\":99.5,\"warning_display\":\"99.5\"}],\"type\":\"metric\",\"type_id\":1,\"description\":\"Metric SLO using sli_specification\",\"timeframe\":\"7d\",\"warning_threshold\":99.5,\"target_threshold\":99,\"query\":{\"numerator\":\"sum:httpservice.hits{*}.as_count() - sum:httpservice.errors{*}.as_count()\",\"denominator\":\"(sum:httpservice.hits{*}.as_count() - sum:httpservice.errors{*}.as_count()) + (sum:httpservice.errors{*}.as_count())\"},\"creator\":{\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"email\":\"team-intg-tools-libs-spam@datadoghq.com\"},\"created_at\":1772041538,\"modified_at\":1772041538,\"sli_specification\":{\"count\":{\"bad_events_formula\":{\"formula\":\"query2\"},\"good_events_formula\":{\"formula\":\"query1 - query2\"},\"queries\":[{\"data_source\":\"metrics\",\"name\":\"query1\",\"query\":\"sum:httpservice.hits{*}.as_count()\"},{\"data_source\":\"metrics\",\"name\":\"query2\",\"query\":\"sum:httpservice.errors{*}.as_count()\"}]}}}],\"error\":null}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "d5693d5e-ee1e-afa7-88d0-69277375e5d9" + }, + { + "httpRequest": { + "headers": {}, + "method": "DELETE", + "path": "/api/v1/slo/7309ff3752fd519f80f65a2ed3247dbb", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"data\":[\"7309ff3752fd519f80f65a2ed3247dbb\"],\"error\":null}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "c0933b3f-30b7-b24a-0ddb-dcdf3c1ea62d" + } +] \ No newline at end of file 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 22c9d6cd3f9..6e756c5a54e 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,19 @@ Feature: Service Level Objectives When the request is sent Then the response status is 200 OK + @team:DataDog/slo-app + Scenario: Create a new metric SLO object using bad events formula 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 - query2"},"bad_events_formula":{"formula":"query2"},"queries":[{"data_source":"metrics","name":"query1","query":"sum:httpservice.hits{*}.as_count()"},{"data_source":"metrics","name":"query2","query":"sum:httpservice.errors{*}.as_count()"}]}},"tags":["env:prod","type:count"],"thresholds":[{"target":99.0,"target_display":"99.0","timeframe":"7d","warning":99.5,"warning_display":"99.5"}],"timeframe":"7d","target_threshold":99.0,"warning_threshold":99.5} + When the request is sent + Then the response status is 200 OK + 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 "bad_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 + @team:DataDog/slo-app Scenario: Create a new metric SLO object using sli_specification returns "OK" response Given new "CreateSLO" request @@ -247,7 +260,7 @@ Feature: Service Level Objectives Scenario: Update an SLO returns "Not Found" response Given new "UpdateSLO" request And request contains "slo_id" parameter from "REPLACE.ME" - And body with value {"description": null, "groups": ["env:prod", "role:mysql"], "monitor_ids": [], "monitor_tags": [], "name": "Custom Metric SLO", "query": {"denominator": "sum:my.custom.metric{*}.as_count()", "numerator": "sum:my.custom.metric{type:good}.as_count()"}, "sli_specification": {"time_slice": {"comparator": "<", "query": {"formulas": [{"formula": "query2/query1"}], "queries": [{"data_source": "metrics", "name": "query1", "query": "sum:trace.servlet.request.hits{*} by {env}.as_count()"}, {"data_source": "metrics", "name": "query1", "query": "sum:trace.servlet.request.errors{*} by {env}.as_count()"}]}, "threshold": 5}}, "tags": ["env:prod", "app:core"], "target_threshold": 99.9, "thresholds": [{"target": 95, "timeframe": "7d"}, {"target": 95, "timeframe": "30d", "warning": 97}], "timeframe": "30d", "type": "metric", "warning_threshold": 99.95} + And body with value {"description": null, "groups": ["env:prod", "role:mysql"], "monitor_ids": [], "monitor_tags": [], "name": "Custom Metric SLO", "query": {"denominator": "sum:my.custom.metric{*}.as_count()", "numerator": "sum:my.custom.metric{type:good}.as_count()"}, "sli_specification": {"time_slice": {"comparator": "<", "query": {"formulas": [{"formula": "query2/query1"}], "queries": [{"data_source": "metrics", "name": "query1", "query": "sum:trace.servlet.request.hits{*} by {env}.as_count()"}, {"data_source": "metrics", "name": "query2", "query": "sum:trace.servlet.request.errors{*} by {env}.as_count()"}]}, "threshold": 5}}, "tags": ["env:prod", "app:core"], "target_threshold": 99.9, "thresholds": [{"target": 95, "timeframe": "7d"}, {"target": 95, "timeframe": "30d", "warning": 97}], "timeframe": "30d", "type": "metric", "warning_threshold": 99.95} When the request is sent Then the response status is 404 Not Found