diff --git a/.apigentools-info b/.apigentools-info index c222bf768a7..cff5f6fb567 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.4", - "regenerated": "2023-05-17 14:44:33.390332", - "spec_repo_commit": "f8bfb8c1" + "regenerated": "2023-05-17 20:57:57.342563", + "spec_repo_commit": "d8186149" }, "v2": { "apigentools_version": "1.6.4", - "regenerated": "2023-05-17 14:44:33.403841", - "spec_repo_commit": "f8bfb8c1" + "regenerated": "2023-05-17 20:57:57.359087", + "spec_repo_commit": "d8186149" } } } \ No newline at end of file diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index 3c8bef22039..e7988d6e5ee 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -2728,6 +2728,7 @@ components: - $ref: '#/components/schemas/FormulaAndFunctionProcessQueryDefinition' - $ref: '#/components/schemas/FormulaAndFunctionApmDependencyStatsQueryDefinition' - $ref: '#/components/schemas/FormulaAndFunctionApmResourceStatsQueryDefinition' + - $ref: '#/components/schemas/FormulaAndFunctionSLOQueryDefinition' type: object FormulaAndFunctionResponseFormat: description: Timeseries or Scalar response. @@ -2739,6 +2740,81 @@ components: x-enum-varnames: - TIMESERIES - SCALAR + FormulaAndFunctionSLODataSource: + description: Data source for SLO measures queries. + enum: + - slo + example: slo + type: string + x-enum-varnames: + - SLO + FormulaAndFunctionSLOGroupMode: + description: Group mode to query measures. + enum: + - overall + - components + example: overall + type: string + x-enum-varnames: + - OVERALL + - COMPONENTS + FormulaAndFunctionSLOMeasure: + description: SLO measures queries. + enum: + - good_events + - bad_events + - slo_status + - error_budget_remaining + - burn_rate + - error_budget_burndown + example: slo_status + type: string + x-enum-varnames: + - GOOD_EVENTS + - BAD_EVENTS + - SLO_STATUS + - ERROR_BUDGET_REMAINING + - BURN_RATE + - ERROR_BUDGET_BURNDOWN + FormulaAndFunctionSLOQueryDefinition: + description: A formula and functions metrics query. + example: + data_source: slo + group_mode: overall + measure: good_events + name: my_slo + slo_id: '12345678910' + slo_query_type: metric + properties: + data_source: + $ref: '#/components/schemas/FormulaAndFunctionSLODataSource' + group_mode: + $ref: '#/components/schemas/FormulaAndFunctionSLOGroupMode' + measure: + $ref: '#/components/schemas/FormulaAndFunctionSLOMeasure' + name: + description: Name of the query for use in formulas. + example: my_slo + type: string + slo_id: + description: ID of an SLO to query measures. + example: '12345678910' + type: string + slo_query_type: + $ref: '#/components/schemas/FormulaAndFunctionSLOQueryType' + required: + - data_source + - slo_id + - measure + type: object + FormulaAndFunctionSLOQueryType: + description: Name of the query for use in formulas. + enum: + - metric + example: metric + type: string + x-enum-varnames: + - METRIC FreeTextWidgetDefinition: description: Free text is a widget that allows you to add headings to your screenboard. Commonly used to state the overall purpose of the dashboard. Only available diff --git a/examples/v1/dashboards/CreateDashboard_3562282606.java b/examples/v1/dashboards/CreateDashboard_3562282606.java new file mode 100644 index 00000000000..9697d51854e --- /dev/null +++ b/examples/v1/dashboards/CreateDashboard_3562282606.java @@ -0,0 +1,98 @@ +// Create a new dashboard with a change widget using formulas and functions slo query + +import com.datadog.api.client.ApiClient; +import com.datadog.api.client.ApiException; +import com.datadog.api.client.v1.api.DashboardsApi; +import com.datadog.api.client.v1.model.ChangeWidgetDefinition; +import com.datadog.api.client.v1.model.ChangeWidgetDefinitionType; +import com.datadog.api.client.v1.model.ChangeWidgetRequest; +import com.datadog.api.client.v1.model.Dashboard; +import com.datadog.api.client.v1.model.DashboardLayoutType; +import com.datadog.api.client.v1.model.FormulaAndFunctionQueryDefinition; +import com.datadog.api.client.v1.model.FormulaAndFunctionResponseFormat; +import com.datadog.api.client.v1.model.FormulaAndFunctionSLODataSource; +import com.datadog.api.client.v1.model.FormulaAndFunctionSLOGroupMode; +import com.datadog.api.client.v1.model.FormulaAndFunctionSLOMeasure; +import com.datadog.api.client.v1.model.FormulaAndFunctionSLOQueryDefinition; +import com.datadog.api.client.v1.model.FormulaAndFunctionSLOQueryType; +import com.datadog.api.client.v1.model.Widget; +import com.datadog.api.client.v1.model.WidgetChangeType; +import com.datadog.api.client.v1.model.WidgetDefinition; +import com.datadog.api.client.v1.model.WidgetFormula; +import com.datadog.api.client.v1.model.WidgetLayout; +import com.datadog.api.client.v1.model.WidgetOrderBy; +import com.datadog.api.client.v1.model.WidgetSort; +import com.datadog.api.client.v1.model.WidgetTextAlign; +import com.datadog.api.client.v1.model.WidgetTime; +import java.util.Arrays; +import java.util.Collections; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = ApiClient.getDefaultApiClient(); + DashboardsApi apiInstance = new DashboardsApi(defaultClient); + + // there is a valid "slo" in the system + String SLO_DATA_0_ID = System.getenv("SLO_DATA_0_ID"); + + Dashboard body = + new Dashboard() + .title("Example-Dashboard") + .widgets( + Collections.singletonList( + new Widget() + .definition( + new WidgetDefinition( + new ChangeWidgetDefinition() + .title("") + .titleSize("16") + .titleAlign(WidgetTextAlign.LEFT) + .time(new WidgetTime()) + .type(ChangeWidgetDefinitionType.CHANGE) + .requests( + Collections.singletonList( + new ChangeWidgetRequest() + .formulas( + Arrays.asList( + new WidgetFormula() + .formula("hour_before(query1)"), + new WidgetFormula().formula("query1"))) + .queries( + Collections.singletonList( + new FormulaAndFunctionQueryDefinition( + new FormulaAndFunctionSLOQueryDefinition() + .name("query1") + .dataSource( + FormulaAndFunctionSLODataSource + .SLO) + .sloId(SLO_DATA_0_ID) + .measure( + FormulaAndFunctionSLOMeasure + .SLO_STATUS) + .groupMode( + FormulaAndFunctionSLOGroupMode + .OVERALL) + .sloQueryType( + FormulaAndFunctionSLOQueryType + .METRIC)))) + .responseFormat( + FormulaAndFunctionResponseFormat.SCALAR) + .orderBy(WidgetOrderBy.CHANGE) + .changeType(WidgetChangeType.ABSOLUTE) + .increaseGood(true) + .orderDir(WidgetSort.ASCENDING))))) + .layout(new WidgetLayout().x(0L).y(0L).width(4L).height(2L)))) + .layoutType(DashboardLayoutType.ORDERED); + + try { + Dashboard result = apiInstance.createDashboard(body); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DashboardsApi#createDashboard"); + 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/FormulaAndFunctionQueryDefinition.java b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionQueryDefinition.java index 6066f947399..5ea90a94090 100644 --- a/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionQueryDefinition.java +++ b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionQueryDefinition.java @@ -345,6 +345,55 @@ public FormulaAndFunctionQueryDefinition deserialize(JsonParser jp, Deserializat e); } + // deserialize FormulaAndFunctionSLOQueryDefinition + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (FormulaAndFunctionSLOQueryDefinition.class.equals(Integer.class) + || FormulaAndFunctionSLOQueryDefinition.class.equals(Long.class) + || FormulaAndFunctionSLOQueryDefinition.class.equals(Float.class) + || FormulaAndFunctionSLOQueryDefinition.class.equals(Double.class) + || FormulaAndFunctionSLOQueryDefinition.class.equals(Boolean.class) + || FormulaAndFunctionSLOQueryDefinition.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((FormulaAndFunctionSLOQueryDefinition.class.equals(Integer.class) + || FormulaAndFunctionSLOQueryDefinition.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((FormulaAndFunctionSLOQueryDefinition.class.equals(Float.class) + || FormulaAndFunctionSLOQueryDefinition.class.equals(Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (FormulaAndFunctionSLOQueryDefinition.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (FormulaAndFunctionSLOQueryDefinition.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = + tree.traverse(jp.getCodec()).readValueAs(FormulaAndFunctionSLOQueryDefinition.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 (!((FormulaAndFunctionSLOQueryDefinition) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log(Level.FINER, "Input data matches schema 'FormulaAndFunctionSLOQueryDefinition'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log( + Level.FINER, + "Input data does not match schema 'FormulaAndFunctionSLOQueryDefinition'", + e); + } + FormulaAndFunctionQueryDefinition ret = new FormulaAndFunctionQueryDefinition(); if (match == 1) { ret.setActualInstance(deserialized); @@ -400,6 +449,11 @@ public FormulaAndFunctionQueryDefinition(FormulaAndFunctionApmResourceStatsQuery setActualInstance(o); } + public FormulaAndFunctionQueryDefinition(FormulaAndFunctionSLOQueryDefinition o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + static { schemas.put( "FormulaAndFunctionMetricQueryDefinition", @@ -416,6 +470,9 @@ public FormulaAndFunctionQueryDefinition(FormulaAndFunctionApmResourceStatsQuery schemas.put( "FormulaAndFunctionApmResourceStatsQueryDefinition", new GenericType() {}); + schemas.put( + "FormulaAndFunctionSLOQueryDefinition", + new GenericType() {}); JSON.registerDescendants( FormulaAndFunctionQueryDefinition.class, Collections.unmodifiableMap(schemas)); } @@ -430,7 +487,7 @@ public Map getSchemas() { * against the oneOf child schemas: FormulaAndFunctionMetricQueryDefinition, * FormulaAndFunctionEventQueryDefinition, FormulaAndFunctionProcessQueryDefinition, * FormulaAndFunctionApmDependencyStatsQueryDefinition, - * FormulaAndFunctionApmResourceStatsQueryDefinition + * FormulaAndFunctionApmResourceStatsQueryDefinition, FormulaAndFunctionSLOQueryDefinition * *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a * composed schema (allOf, anyOf, oneOf). @@ -466,6 +523,11 @@ public void setActualInstance(Object instance) { super.setActualInstance(instance); return; } + if (JSON.isInstanceOf( + FormulaAndFunctionSLOQueryDefinition.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } if (JSON.isInstanceOf(UnparsedObject.class, instance, new HashSet>())) { super.setActualInstance(instance); @@ -475,19 +537,20 @@ public void setActualInstance(Object instance) { "Invalid instance type. Must be FormulaAndFunctionMetricQueryDefinition," + " FormulaAndFunctionEventQueryDefinition, FormulaAndFunctionProcessQueryDefinition," + " FormulaAndFunctionApmDependencyStatsQueryDefinition," - + " FormulaAndFunctionApmResourceStatsQueryDefinition"); + + " FormulaAndFunctionApmResourceStatsQueryDefinition," + + " FormulaAndFunctionSLOQueryDefinition"); } /** * Get the actual instance, which can be the following: FormulaAndFunctionMetricQueryDefinition, * FormulaAndFunctionEventQueryDefinition, FormulaAndFunctionProcessQueryDefinition, * FormulaAndFunctionApmDependencyStatsQueryDefinition, - * FormulaAndFunctionApmResourceStatsQueryDefinition + * FormulaAndFunctionApmResourceStatsQueryDefinition, FormulaAndFunctionSLOQueryDefinition * * @return The actual instance (FormulaAndFunctionMetricQueryDefinition, * FormulaAndFunctionEventQueryDefinition, FormulaAndFunctionProcessQueryDefinition, * FormulaAndFunctionApmDependencyStatsQueryDefinition, - * FormulaAndFunctionApmResourceStatsQueryDefinition) + * FormulaAndFunctionApmResourceStatsQueryDefinition, FormulaAndFunctionSLOQueryDefinition) */ @Override public Object getActualInstance() { @@ -557,4 +620,16 @@ public FormulaAndFunctionProcessQueryDefinition getFormulaAndFunctionProcessQuer getFormulaAndFunctionApmResourceStatsQueryDefinition() throws ClassCastException { return (FormulaAndFunctionApmResourceStatsQueryDefinition) super.getActualInstance(); } + + /** + * Get the actual instance of `FormulaAndFunctionSLOQueryDefinition`. If the actual instance is + * not `FormulaAndFunctionSLOQueryDefinition`, the ClassCastException will be thrown. + * + * @return The actual instance of `FormulaAndFunctionSLOQueryDefinition` + * @throws ClassCastException if the instance is not `FormulaAndFunctionSLOQueryDefinition` + */ + public FormulaAndFunctionSLOQueryDefinition getFormulaAndFunctionSLOQueryDefinition() + throws ClassCastException { + return (FormulaAndFunctionSLOQueryDefinition) super.getActualInstance(); + } } diff --git a/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLODataSource.java b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLODataSource.java new file mode 100644 index 00000000000..c7f1d05fee3 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLODataSource.java @@ -0,0 +1,95 @@ +/* + * 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.JsonValue; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** Data source for SLO measures queries. */ +@JsonSerialize( + using = FormulaAndFunctionSLODataSource.FormulaAndFunctionSLODataSourceSerializer.class) +public class FormulaAndFunctionSLODataSource { + + public static final FormulaAndFunctionSLODataSource SLO = + new FormulaAndFunctionSLODataSource("slo"); + + private static final Set allowedValues = new HashSet(Arrays.asList("slo")); + + private String value; + + public boolean isValid() { + return allowedValues.contains(this.value); + } + + FormulaAndFunctionSLODataSource(String value) { + this.value = value; + } + + public static class FormulaAndFunctionSLODataSourceSerializer + extends StdSerializer { + public FormulaAndFunctionSLODataSourceSerializer(Class t) { + super(t); + } + + public FormulaAndFunctionSLODataSourceSerializer() { + this(null); + } + + @Override + public void serialize( + FormulaAndFunctionSLODataSource value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.value); + } + } + + @JsonValue + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + /** Return true if this FormulaAndFunctionSLODataSource object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return this.value.equals(((FormulaAndFunctionSLODataSource) o).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static FormulaAndFunctionSLODataSource fromValue(String value) { + return new FormulaAndFunctionSLODataSource(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOGroupMode.java b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOGroupMode.java new file mode 100644 index 00000000000..26be276bbb2 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOGroupMode.java @@ -0,0 +1,98 @@ +/* + * 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.JsonValue; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** Group mode to query measures. */ +@JsonSerialize( + using = FormulaAndFunctionSLOGroupMode.FormulaAndFunctionSLOGroupModeSerializer.class) +public class FormulaAndFunctionSLOGroupMode { + + public static final FormulaAndFunctionSLOGroupMode OVERALL = + new FormulaAndFunctionSLOGroupMode("overall"); + public static final FormulaAndFunctionSLOGroupMode COMPONENTS = + new FormulaAndFunctionSLOGroupMode("components"); + + private static final Set allowedValues = + new HashSet(Arrays.asList("overall", "components")); + + private String value; + + public boolean isValid() { + return allowedValues.contains(this.value); + } + + FormulaAndFunctionSLOGroupMode(String value) { + this.value = value; + } + + public static class FormulaAndFunctionSLOGroupModeSerializer + extends StdSerializer { + public FormulaAndFunctionSLOGroupModeSerializer(Class t) { + super(t); + } + + public FormulaAndFunctionSLOGroupModeSerializer() { + this(null); + } + + @Override + public void serialize( + FormulaAndFunctionSLOGroupMode value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.value); + } + } + + @JsonValue + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + /** Return true if this FormulaAndFunctionSLOGroupMode object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return this.value.equals(((FormulaAndFunctionSLOGroupMode) o).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static FormulaAndFunctionSLOGroupMode fromValue(String value) { + return new FormulaAndFunctionSLOGroupMode(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOMeasure.java b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOMeasure.java new file mode 100644 index 00000000000..0322c651d1e --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOMeasure.java @@ -0,0 +1,112 @@ +/* + * 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.JsonValue; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** SLO measures queries. */ +@JsonSerialize(using = FormulaAndFunctionSLOMeasure.FormulaAndFunctionSLOMeasureSerializer.class) +public class FormulaAndFunctionSLOMeasure { + + public static final FormulaAndFunctionSLOMeasure GOOD_EVENTS = + new FormulaAndFunctionSLOMeasure("good_events"); + public static final FormulaAndFunctionSLOMeasure BAD_EVENTS = + new FormulaAndFunctionSLOMeasure("bad_events"); + public static final FormulaAndFunctionSLOMeasure SLO_STATUS = + new FormulaAndFunctionSLOMeasure("slo_status"); + public static final FormulaAndFunctionSLOMeasure ERROR_BUDGET_REMAINING = + new FormulaAndFunctionSLOMeasure("error_budget_remaining"); + public static final FormulaAndFunctionSLOMeasure BURN_RATE = + new FormulaAndFunctionSLOMeasure("burn_rate"); + public static final FormulaAndFunctionSLOMeasure ERROR_BUDGET_BURNDOWN = + new FormulaAndFunctionSLOMeasure("error_budget_burndown"); + + private static final Set allowedValues = + new HashSet( + Arrays.asList( + "good_events", + "bad_events", + "slo_status", + "error_budget_remaining", + "burn_rate", + "error_budget_burndown")); + + private String value; + + public boolean isValid() { + return allowedValues.contains(this.value); + } + + FormulaAndFunctionSLOMeasure(String value) { + this.value = value; + } + + public static class FormulaAndFunctionSLOMeasureSerializer + extends StdSerializer { + public FormulaAndFunctionSLOMeasureSerializer(Class t) { + super(t); + } + + public FormulaAndFunctionSLOMeasureSerializer() { + this(null); + } + + @Override + public void serialize( + FormulaAndFunctionSLOMeasure value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.value); + } + } + + @JsonValue + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + /** Return true if this FormulaAndFunctionSLOMeasure object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return this.value.equals(((FormulaAndFunctionSLOMeasure) o).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static FormulaAndFunctionSLOMeasure fromValue(String value) { + return new FormulaAndFunctionSLOMeasure(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOQueryDefinition.java b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOQueryDefinition.java new file mode 100644 index 00000000000..ed4dabd9ae5 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOQueryDefinition.java @@ -0,0 +1,251 @@ +/* + * 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 formula and functions metrics query. */ +@JsonPropertyOrder({ + FormulaAndFunctionSLOQueryDefinition.JSON_PROPERTY_DATA_SOURCE, + FormulaAndFunctionSLOQueryDefinition.JSON_PROPERTY_GROUP_MODE, + FormulaAndFunctionSLOQueryDefinition.JSON_PROPERTY_MEASURE, + FormulaAndFunctionSLOQueryDefinition.JSON_PROPERTY_NAME, + FormulaAndFunctionSLOQueryDefinition.JSON_PROPERTY_SLO_ID, + FormulaAndFunctionSLOQueryDefinition.JSON_PROPERTY_SLO_QUERY_TYPE +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class FormulaAndFunctionSLOQueryDefinition { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_DATA_SOURCE = "data_source"; + private FormulaAndFunctionSLODataSource dataSource; + + public static final String JSON_PROPERTY_GROUP_MODE = "group_mode"; + private FormulaAndFunctionSLOGroupMode groupMode; + + public static final String JSON_PROPERTY_MEASURE = "measure"; + private FormulaAndFunctionSLOMeasure measure; + + public static final String JSON_PROPERTY_NAME = "name"; + private String name; + + public static final String JSON_PROPERTY_SLO_ID = "slo_id"; + private String sloId; + + public static final String JSON_PROPERTY_SLO_QUERY_TYPE = "slo_query_type"; + private FormulaAndFunctionSLOQueryType sloQueryType; + + public FormulaAndFunctionSLOQueryDefinition() {} + + @JsonCreator + public FormulaAndFunctionSLOQueryDefinition( + @JsonProperty(required = true, value = JSON_PROPERTY_DATA_SOURCE) + FormulaAndFunctionSLODataSource dataSource, + @JsonProperty(required = true, value = JSON_PROPERTY_MEASURE) + FormulaAndFunctionSLOMeasure measure, + @JsonProperty(required = true, value = JSON_PROPERTY_SLO_ID) String sloId) { + this.dataSource = dataSource; + this.unparsed |= !dataSource.isValid(); + this.measure = measure; + this.unparsed |= !measure.isValid(); + this.sloId = sloId; + } + + public FormulaAndFunctionSLOQueryDefinition dataSource( + FormulaAndFunctionSLODataSource dataSource) { + this.dataSource = dataSource; + this.unparsed |= !dataSource.isValid(); + return this; + } + + /** + * Data source for SLO measures queries. + * + * @return dataSource + */ + @JsonProperty(JSON_PROPERTY_DATA_SOURCE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public FormulaAndFunctionSLODataSource getDataSource() { + return dataSource; + } + + public void setDataSource(FormulaAndFunctionSLODataSource dataSource) { + if (!dataSource.isValid()) { + this.unparsed = true; + } + this.dataSource = dataSource; + } + + public FormulaAndFunctionSLOQueryDefinition groupMode(FormulaAndFunctionSLOGroupMode groupMode) { + this.groupMode = groupMode; + this.unparsed |= !groupMode.isValid(); + return this; + } + + /** + * Group mode to query measures. + * + * @return groupMode + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_GROUP_MODE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public FormulaAndFunctionSLOGroupMode getGroupMode() { + return groupMode; + } + + public void setGroupMode(FormulaAndFunctionSLOGroupMode groupMode) { + if (!groupMode.isValid()) { + this.unparsed = true; + } + this.groupMode = groupMode; + } + + public FormulaAndFunctionSLOQueryDefinition measure(FormulaAndFunctionSLOMeasure measure) { + this.measure = measure; + this.unparsed |= !measure.isValid(); + return this; + } + + /** + * SLO measures queries. + * + * @return measure + */ + @JsonProperty(JSON_PROPERTY_MEASURE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public FormulaAndFunctionSLOMeasure getMeasure() { + return measure; + } + + public void setMeasure(FormulaAndFunctionSLOMeasure measure) { + if (!measure.isValid()) { + this.unparsed = true; + } + this.measure = measure; + } + + public FormulaAndFunctionSLOQueryDefinition name(String name) { + this.name = name; + return this; + } + + /** + * Name of the query for use in formulas. + * + * @return name + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public FormulaAndFunctionSLOQueryDefinition sloId(String sloId) { + this.sloId = sloId; + return this; + } + + /** + * ID of an SLO to query measures. + * + * @return sloId + */ + @JsonProperty(JSON_PROPERTY_SLO_ID) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getSloId() { + return sloId; + } + + public void setSloId(String sloId) { + this.sloId = sloId; + } + + public FormulaAndFunctionSLOQueryDefinition sloQueryType( + FormulaAndFunctionSLOQueryType sloQueryType) { + this.sloQueryType = sloQueryType; + this.unparsed |= !sloQueryType.isValid(); + return this; + } + + /** + * Name of the query for use in formulas. + * + * @return sloQueryType + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SLO_QUERY_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public FormulaAndFunctionSLOQueryType getSloQueryType() { + return sloQueryType; + } + + public void setSloQueryType(FormulaAndFunctionSLOQueryType sloQueryType) { + if (!sloQueryType.isValid()) { + this.unparsed = true; + } + this.sloQueryType = sloQueryType; + } + + /** Return true if this FormulaAndFunctionSLOQueryDefinition object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FormulaAndFunctionSLOQueryDefinition formulaAndFunctionSloQueryDefinition = + (FormulaAndFunctionSLOQueryDefinition) o; + return Objects.equals(this.dataSource, formulaAndFunctionSloQueryDefinition.dataSource) + && Objects.equals(this.groupMode, formulaAndFunctionSloQueryDefinition.groupMode) + && Objects.equals(this.measure, formulaAndFunctionSloQueryDefinition.measure) + && Objects.equals(this.name, formulaAndFunctionSloQueryDefinition.name) + && Objects.equals(this.sloId, formulaAndFunctionSloQueryDefinition.sloId) + && Objects.equals(this.sloQueryType, formulaAndFunctionSloQueryDefinition.sloQueryType); + } + + @Override + public int hashCode() { + return Objects.hash(dataSource, groupMode, measure, name, sloId, sloQueryType); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class FormulaAndFunctionSLOQueryDefinition {\n"); + sb.append(" dataSource: ").append(toIndentedString(dataSource)).append("\n"); + sb.append(" groupMode: ").append(toIndentedString(groupMode)).append("\n"); + sb.append(" measure: ").append(toIndentedString(measure)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" sloId: ").append(toIndentedString(sloId)).append("\n"); + sb.append(" sloQueryType: ").append(toIndentedString(sloQueryType)).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/FormulaAndFunctionSLOQueryType.java b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOQueryType.java new file mode 100644 index 00000000000..b1f25033476 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/FormulaAndFunctionSLOQueryType.java @@ -0,0 +1,95 @@ +/* + * 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.JsonValue; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +/** Name of the query for use in formulas. */ +@JsonSerialize( + using = FormulaAndFunctionSLOQueryType.FormulaAndFunctionSLOQueryTypeSerializer.class) +public class FormulaAndFunctionSLOQueryType { + + public static final FormulaAndFunctionSLOQueryType METRIC = + new FormulaAndFunctionSLOQueryType("metric"); + + private static final Set allowedValues = new HashSet(Arrays.asList("metric")); + + private String value; + + public boolean isValid() { + return allowedValues.contains(this.value); + } + + FormulaAndFunctionSLOQueryType(String value) { + this.value = value; + } + + public static class FormulaAndFunctionSLOQueryTypeSerializer + extends StdSerializer { + public FormulaAndFunctionSLOQueryTypeSerializer(Class t) { + super(t); + } + + public FormulaAndFunctionSLOQueryTypeSerializer() { + this(null); + } + + @Override + public void serialize( + FormulaAndFunctionSLOQueryType value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.value); + } + } + + @JsonValue + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + /** Return true if this FormulaAndFunctionSLOQueryType object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return this.value.equals(((FormulaAndFunctionSLOQueryType) o).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static FormulaAndFunctionSLOQueryType fromValue(String value) { + return new FormulaAndFunctionSLOQueryType(value); + } +} diff --git a/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query.freeze b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query.freeze new file mode 100644 index 00000000000..8ebe85edb58 --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query.freeze @@ -0,0 +1 @@ +2023-05-16T22:06:53.853Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query.json b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query.json new file mode 100644 index 00000000000..7147253649c --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query.json @@ -0,0 +1,114 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"name\": \"Test-Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query-1684274813\", \"query\": {\"denominator\": \"sum:httpservice.hits{!code:3xx}.as_count()\", \"numerator\": \"sum:httpservice.hits{code:2xx}.as_count()\"}, \"thresholds\": [{\"target\": 95.0, \"timeframe\": \"7d\", \"warning\": 98.0}], \"type\": \"metric\"}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v1/slo", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"data\":[{\"id\":\"1c7cc520f98356d6b79adb1f8dbdef60\",\"name\":\"Test-Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query-1684274813\",\"tags\":[],\"monitor_tags\":[],\"thresholds\":[{\"timeframe\":\"7d\",\"target\":95.0,\"target_display\":\"95.\",\"warning\":98.0,\"warning_display\":\"98.\"}],\"type\":\"metric\",\"type_id\":1,\"description\":\"\",\"timeframe\":\"7d\",\"warning_threshold\":98,\"target_threshold\":95,\"query\":{\"denominator\":\"sum:httpservice.hits{!code:3xx}.as_count()\",\"numerator\":\"sum:httpservice.hits{code:2xx}.as_count()\"},\"creator\":{\"name\":null,\"handle\":\"frog@datadoghq.com\",\"email\":\"frog@datadoghq.com\"},\"created_at\":1684274814,\"modified_at\":1684274814}],\"error\":null}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "561c5e1d-53e3-cde4-dbbb-ed6e66af81d3" + }, + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"layout_type\":\"ordered\",\"title\":\"Test-Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query-1684274813\",\"widgets\":[{\"definition\":{\"requests\":[{\"change_type\":\"absolute\",\"formulas\":[{\"formula\":\"hour_before(query1)\"},{\"formula\":\"query1\"}],\"increase_good\":true,\"order_by\":\"change\",\"order_dir\":\"asc\",\"queries\":[{\"data_source\":\"slo\",\"group_mode\":\"overall\",\"measure\":\"slo_status\",\"name\":\"query1\",\"slo_id\":\"1c7cc520f98356d6b79adb1f8dbdef60\",\"slo_query_type\":\"metric\"}],\"response_format\":\"scalar\"}],\"time\":{},\"title\":\"\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"change\"},\"layout\":{\"height\":2,\"width\":4,\"x\":0,\"y\":0}}]}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v1/dashboard", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"id\":\"8kt-y74-2i3\",\"title\":\"Test-Create_a_new_dashboard_with_a_change_widget_using_formulas_and_functions_slo_query-1684274813\",\"description\":null,\"author_handle\":\"frog@datadoghq.com\",\"author_name\":null,\"layout_type\":\"ordered\",\"url\":\"/dashboard/8kt-y74-2i3/test-createanewdashboardwithachangewidgetusingformulasandfunctionssloquery-16842\",\"is_read_only\":false,\"template_variables\":null,\"widgets\":[{\"definition\":{\"requests\":[{\"change_type\":\"absolute\",\"formulas\":[{\"formula\":\"hour_before(query1)\"},{\"formula\":\"query1\"}],\"increase_good\":true,\"order_by\":\"change\",\"order_dir\":\"asc\",\"queries\":[{\"data_source\":\"slo\",\"group_mode\":\"overall\",\"measure\":\"slo_status\",\"name\":\"query1\",\"slo_id\":\"1c7cc520f98356d6b79adb1f8dbdef60\",\"slo_query_type\":\"metric\"}],\"response_format\":\"scalar\"}],\"time\":{},\"title\":\"\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"change\"},\"layout\":{\"height\":2,\"width\":4,\"x\":0,\"y\":0},\"id\":8047848064178828}],\"notify_list\":null,\"created_at\":\"2023-05-16T22:06:54.344881+00:00\",\"modified_at\":\"2023-05-16T22:06:54.344881+00:00\",\"restricted_roles\":[]}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "ccbdcca4-ee0e-571d-3ed5-20f17d875ff4" + }, + { + "httpRequest": { + "headers": {}, + "method": "DELETE", + "path": "/api/v1/dashboard/8kt-y74-2i3", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"deleted_dashboard_id\":\"8kt-y74-2i3\"}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "5734ef8d-c2b0-db9c-9381-810e619f85cd" + }, + { + "httpRequest": { + "headers": {}, + "method": "DELETE", + "path": "/api/v1/slo/1c7cc520f98356d6b79adb1f8dbdef60", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"data\":[\"1c7cc520f98356d6b79adb1f8dbdef60\"],\"error\":null}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "9fef3929-95a3-e903-5947-add8232beaaa" + } +] \ No newline at end of file diff --git a/src/test/resources/com/datadog/api/client/v1/api/dashboards.feature b/src/test/resources/com/datadog/api/client/v1/api/dashboards.feature index b417bf5e738..80602421b55 100644 --- a/src/test/resources/com/datadog/api/client/v1/api/dashboards.feature +++ b/src/test/resources/com/datadog/api/client/v1/api/dashboards.feature @@ -72,6 +72,27 @@ Feature: Dashboards And the response "widgets[0].definition.requests[0].profile_metrics_query.compute.facet" is equal to "@prof_core_cpu_cores" And the response "widgets[0].definition.requests[0].profile_metrics_query.compute.aggregation" is equal to "sum" + @team:DataDog/dashboards-backend + Scenario: Create a new dashboard with a change widget using formulas and functions slo query + Given there is a valid "slo" in the system + And new "CreateDashboard" request + And body with value { "title": "{{ unique }}", "widgets": [ { "definition": {"title": "", "title_size": "16", "title_align": "left", "time": {}, "type": "change", "requests": [ {"formulas": [ { "formula": "hour_before(query1)" }, { "formula": "query1" } ], "queries": [ {"name": "query1", "data_source": "slo", "slo_id": "{{ slo.data[0].id }}", "measure": "slo_status", "group_mode": "overall", "slo_query_type": "metric" } ], "response_format": "scalar", "order_by": "change", "change_type": "absolute", "increase_good": true, "order_dir": "asc" } ] }, "layout": { "x":0, "y": 0, "width": 4, "height": 2 } } ], "layout_type": "ordered" } + When the request is sent + Then the response status is 200 OK + And the response "widgets[0].definition.requests[0].response_format" is equal to "scalar" + And the response "widgets[0].definition.requests[0].increase_good" is equal to true + And the response "widgets[0].definition.requests[0].order_by" is equal to "change" + And the response "widgets[0].definition.requests[0].change_type" is equal to "absolute" + And the response "widgets[0].definition.requests[0].order_dir" is equal to "asc" + And the response "widgets[0].definition.requests[0].queries[0].data_source" is equal to "slo" + And the response "widgets[0].definition.requests[0].queries[0].name" is equal to "query1" + And the response "widgets[0].definition.requests[0].queries[0].group_mode" is equal to "overall" + And the response "widgets[0].definition.requests[0].queries[0].measure" is equal to "slo_status" + And the response "widgets[0].definition.requests[0].queries[0].slo_query_type" is equal to "metric" + And the response "widgets[0].definition.requests[0].queries[0].slo_id" has the same value as "slo.data[0].id" + And the response "widgets[0].definition.requests[0].formulas[0].formula" is equal to "hour_before(query1)" + And the response "widgets[0].definition.requests[0].formulas[1].formula" is equal to "query1" + @team:DataDog/dashboards-backend Scenario: Create a new dashboard with a formulas and functions change widget Given new "CreateDashboard" request