diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index e4c94965900..4fc8dbe3785 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -7255,6 +7255,12 @@ components: Monitor: description: Object describing a monitor. properties: + assets: + description: The list of monitor assets tied to a monitor, which represents + key links for users to take action on monitor alerts (for example, runbooks). + items: + $ref: '#/components/schemas/MonitorAsset' + type: array created: description: Timestamp of the monitor creation. format: date-time @@ -7338,6 +7344,52 @@ components: - type - query type: object + MonitorAsset: + description: 'Represents key links tied to a monitor to help users take action + on alerts. + + This feature is in Preview and only available to users with the feature enabled.' + properties: + category: + $ref: '#/components/schemas/MonitorAssetCategory' + name: + description: Name for the monitor asset + example: Monitor Runbook + type: string + resource_key: + description: Represents the identifier of the internal Datadog resource + that this asset represents. IDs in this field should be passed in as strings. + example: '12345' + type: string + resource_type: + $ref: '#/components/schemas/MonitorAssetResourceType' + url: + description: URL link for the asset. For links with an internal resource + type set, this should be the relative path to where the Datadog domain + is appended internally. For external links, this should be the full URL + path. + example: /notebooks/12345 + type: string + required: + - name + - url + - category + type: object + MonitorAssetCategory: + description: Indicates the type of asset this entity represents on a monitor. + enum: + - runbook + example: runbook + type: string + x-enum-varnames: + - RUNBOOK + MonitorAssetResourceType: + description: Type of internal Datadog resource associated with a monitor asset. + enum: + - notebook + type: string + x-enum-varnames: + - NOTEBOOK MonitorDeviceID: description: ID of the device the Synthetics monitor is running on. Same as `SyntheticsDeviceID`. @@ -8452,6 +8504,13 @@ components: MonitorUpdateRequest: description: Object describing a monitor update request. properties: + assets: + description: The list of monitor assets tied to a monitor, which represents + key links for users to take action on monitor alerts (for example, runbooks). + items: + $ref: '#/components/schemas/MonitorAsset' + nullable: true + type: array created: description: Timestamp of the monitor creation. format: date-time @@ -31584,6 +31643,13 @@ paths: required: false schema: type: boolean + - description: If this argument is set to `true`, the returned data includes + all assets tied to this monitor. + in: query + name: with_assets + required: false + schema: + type: boolean responses: '200': content: diff --git a/examples/v1/monitors/CreateMonitor_3541766733.java b/examples/v1/monitors/CreateMonitor_3541766733.java new file mode 100644 index 00000000000..23bdc403953 --- /dev/null +++ b/examples/v1/monitors/CreateMonitor_3541766733.java @@ -0,0 +1,57 @@ +// Create a monitor with assets returns "OK" response + +import com.datadog.api.client.ApiClient; +import com.datadog.api.client.ApiException; +import com.datadog.api.client.v1.api.MonitorsApi; +import com.datadog.api.client.v1.model.Monitor; +import com.datadog.api.client.v1.model.MonitorAsset; +import com.datadog.api.client.v1.model.MonitorAssetCategory; +import com.datadog.api.client.v1.model.MonitorAssetResourceType; +import com.datadog.api.client.v1.model.MonitorOptions; +import com.datadog.api.client.v1.model.MonitorOptionsSchedulingOptions; +import com.datadog.api.client.v1.model.MonitorOptionsSchedulingOptionsEvaluationWindow; +import com.datadog.api.client.v1.model.MonitorThresholds; +import com.datadog.api.client.v1.model.MonitorType; +import java.util.Collections; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = ApiClient.getDefaultApiClient(); + MonitorsApi apiInstance = new MonitorsApi(defaultClient); + + Monitor body = + new Monitor() + .assets( + Collections.singletonList( + new MonitorAsset() + .category(MonitorAssetCategory.RUNBOOK) + .name("Monitor Runbook") + .resourceKey("12345") + .resourceType(MonitorAssetResourceType.NOTEBOOK) + .url("/notebooks/12345"))) + .name("Example-Monitor") + .type(MonitorType.METRIC_ALERT) + .query("avg(current_1mo):avg:system.load.5{*} > 0.5") + .message("some message Notify: @hipchat-channel") + .options( + new MonitorOptions() + .thresholds(new MonitorThresholds().critical(0.5)) + .schedulingOptions( + new MonitorOptionsSchedulingOptions() + .evaluationWindow( + new MonitorOptionsSchedulingOptionsEvaluationWindow() + .dayStarts("04:00") + .monthStarts(1)))); + + try { + Monitor result = apiInstance.createMonitor(body); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling MonitorsApi#createMonitor"); + 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/api/MonitorsApi.java b/src/main/java/com/datadog/api/client/v1/api/MonitorsApi.java index 6ff102148a8..19a7de551a3 100644 --- a/src/main/java/com/datadog/api/client/v1/api/MonitorsApi.java +++ b/src/main/java/com/datadog/api/client/v1/api/MonitorsApi.java @@ -863,6 +863,7 @@ public CompletableFuture> deleteMonitorWithHttpInfoA public static class GetMonitorOptionalParameters { private String groupStates; private Boolean withDowntimes; + private Boolean withAssets; /** * Set groupStates. @@ -888,6 +889,18 @@ public GetMonitorOptionalParameters withDowntimes(Boolean withDowntimes) { this.withDowntimes = withDowntimes; return this; } + + /** + * Set withAssets. + * + * @param withAssets If this argument is set to true, the returned data includes + * all assets tied to this monitor. (optional) + * @return GetMonitorOptionalParameters + */ + public GetMonitorOptionalParameters withAssets(Boolean withAssets) { + this.withAssets = withAssets; + return this; + } } /** @@ -981,6 +994,7 @@ public ApiResponse getMonitorWithHttpInfo( } String groupStates = parameters.groupStates; Boolean withDowntimes = parameters.withDowntimes; + Boolean withAssets = parameters.withAssets; // create path and map variables String localVarPath = "/api/v1/monitor/{monitor_id}" @@ -991,6 +1005,7 @@ public ApiResponse getMonitorWithHttpInfo( localVarQueryParams.addAll(apiClient.parameterToPairs("", "group_states", groupStates)); localVarQueryParams.addAll(apiClient.parameterToPairs("", "with_downtimes", withDowntimes)); + localVarQueryParams.addAll(apiClient.parameterToPairs("", "with_assets", withAssets)); Invocation.Builder builder = apiClient.createBuilder( @@ -1035,6 +1050,7 @@ public CompletableFuture> getMonitorWithHttpInfoAsync( } String groupStates = parameters.groupStates; Boolean withDowntimes = parameters.withDowntimes; + Boolean withAssets = parameters.withAssets; // create path and map variables String localVarPath = "/api/v1/monitor/{monitor_id}" @@ -1045,6 +1061,7 @@ public CompletableFuture> getMonitorWithHttpInfoAsync( localVarQueryParams.addAll(apiClient.parameterToPairs("", "group_states", groupStates)); localVarQueryParams.addAll(apiClient.parameterToPairs("", "with_downtimes", withDowntimes)); + localVarQueryParams.addAll(apiClient.parameterToPairs("", "with_assets", withAssets)); Invocation.Builder builder; try { diff --git a/src/main/java/com/datadog/api/client/v1/model/Monitor.java b/src/main/java/com/datadog/api/client/v1/model/Monitor.java index 4ac05d7a48e..3b2128a1603 100644 --- a/src/main/java/com/datadog/api/client/v1/model/Monitor.java +++ b/src/main/java/com/datadog/api/client/v1/model/Monitor.java @@ -23,6 +23,7 @@ /** Object describing a monitor. */ @JsonPropertyOrder({ + Monitor.JSON_PROPERTY_ASSETS, Monitor.JSON_PROPERTY_CREATED, Monitor.JSON_PROPERTY_CREATOR, Monitor.JSON_PROPERTY_DELETED, @@ -46,6 +47,9 @@ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") public class Monitor { @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_ASSETS = "assets"; + private List assets = null; + public static final String JSON_PROPERTY_CREATED = "created"; private OffsetDateTime created; @@ -111,6 +115,40 @@ public Monitor( this.unparsed |= !type.isValid(); } + public Monitor assets(List assets) { + this.assets = assets; + for (MonitorAsset item : assets) { + this.unparsed |= item.unparsed; + } + return this; + } + + public Monitor addAssetsItem(MonitorAsset assetsItem) { + if (this.assets == null) { + this.assets = new ArrayList<>(); + } + this.assets.add(assetsItem); + this.unparsed |= assetsItem.unparsed; + return this; + } + + /** + * The list of monitor assets tied to a monitor, which represents key links for users to take + * action on monitor alerts (for example, runbooks). + * + * @return assets + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_ASSETS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getAssets() { + return assets; + } + + public void setAssets(List assets) { + this.assets = assets; + } + /** * Timestamp of the monitor creation. * @@ -560,7 +598,8 @@ public boolean equals(Object o) { return false; } Monitor monitor = (Monitor) o; - return Objects.equals(this.created, monitor.created) + return Objects.equals(this.assets, monitor.assets) + && Objects.equals(this.created, monitor.created) && Objects.equals(this.creator, monitor.creator) && Objects.equals(this.deleted, monitor.deleted) && Objects.equals(this.draftStatus, monitor.draftStatus) @@ -584,6 +623,7 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash( + assets, created, creator, deleted, @@ -609,6 +649,7 @@ public int hashCode() { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class Monitor {\n"); + sb.append(" assets: ").append(toIndentedString(assets)).append("\n"); sb.append(" created: ").append(toIndentedString(created)).append("\n"); sb.append(" creator: ").append(toIndentedString(creator)).append("\n"); sb.append(" deleted: ").append(toIndentedString(deleted)).append("\n"); diff --git a/src/main/java/com/datadog/api/client/v1/model/MonitorAsset.java b/src/main/java/com/datadog/api/client/v1/model/MonitorAsset.java new file mode 100644 index 00000000000..06f990165f9 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/MonitorAsset.java @@ -0,0 +1,270 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v1.model; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Represents key links tied to a monitor to help users take action on alerts. This feature is in + * Preview and only available to users with the feature enabled. + */ +@JsonPropertyOrder({ + MonitorAsset.JSON_PROPERTY_CATEGORY, + MonitorAsset.JSON_PROPERTY_NAME, + MonitorAsset.JSON_PROPERTY_RESOURCE_KEY, + MonitorAsset.JSON_PROPERTY_RESOURCE_TYPE, + MonitorAsset.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class MonitorAsset { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_CATEGORY = "category"; + private MonitorAssetCategory category; + + public static final String JSON_PROPERTY_NAME = "name"; + private String name; + + public static final String JSON_PROPERTY_RESOURCE_KEY = "resource_key"; + private String resourceKey; + + public static final String JSON_PROPERTY_RESOURCE_TYPE = "resource_type"; + private MonitorAssetResourceType resourceType; + + public static final String JSON_PROPERTY_URL = "url"; + private String url; + + public MonitorAsset() {} + + @JsonCreator + public MonitorAsset( + @JsonProperty(required = true, value = JSON_PROPERTY_CATEGORY) MonitorAssetCategory category, + @JsonProperty(required = true, value = JSON_PROPERTY_NAME) String name, + @JsonProperty(required = true, value = JSON_PROPERTY_URL) String url) { + this.category = category; + this.unparsed |= !category.isValid(); + this.name = name; + this.url = url; + } + + public MonitorAsset category(MonitorAssetCategory category) { + this.category = category; + this.unparsed |= !category.isValid(); + return this; + } + + /** + * Indicates the type of asset this entity represents on a monitor. + * + * @return category + */ + @JsonProperty(JSON_PROPERTY_CATEGORY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public MonitorAssetCategory getCategory() { + return category; + } + + public void setCategory(MonitorAssetCategory category) { + if (!category.isValid()) { + this.unparsed = true; + } + this.category = category; + } + + public MonitorAsset name(String name) { + this.name = name; + return this; + } + + /** + * Name for the monitor asset + * + * @return name + */ + @JsonProperty(JSON_PROPERTY_NAME) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public MonitorAsset resourceKey(String resourceKey) { + this.resourceKey = resourceKey; + return this; + } + + /** + * Represents the identifier of the internal Datadog resource that this asset represents. IDs in + * this field should be passed in as strings. + * + * @return resourceKey + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_RESOURCE_KEY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getResourceKey() { + return resourceKey; + } + + public void setResourceKey(String resourceKey) { + this.resourceKey = resourceKey; + } + + public MonitorAsset resourceType(MonitorAssetResourceType resourceType) { + this.resourceType = resourceType; + this.unparsed |= !resourceType.isValid(); + return this; + } + + /** + * Type of internal Datadog resource associated with a monitor asset. + * + * @return resourceType + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_RESOURCE_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public MonitorAssetResourceType getResourceType() { + return resourceType; + } + + public void setResourceType(MonitorAssetResourceType resourceType) { + if (!resourceType.isValid()) { + this.unparsed = true; + } + this.resourceType = resourceType; + } + + public MonitorAsset url(String url) { + this.url = url; + return this; + } + + /** + * URL link for the asset. For links with an internal resource type set, this should be the + * relative path to where the Datadog domain is appended internally. For external links, this + * should be the full URL path. + * + * @return url + */ + @JsonProperty(JSON_PROPERTY_URL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + /** + * A container for additional, undeclared properties. This is a holder for any undeclared + * properties as specified with the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. If the property + * does not already exist, create it otherwise replace it. + * + * @param key The arbitrary key to set + * @param value The associated value + * @return MonitorAsset + */ + @JsonAnySetter + public MonitorAsset putAdditionalProperty(String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) property. + * + * @return The additional properties + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * + * @param key The arbitrary key to get + * @return The specific additional property for the given key + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + + /** Return true if this MonitorAsset object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MonitorAsset monitorAsset = (MonitorAsset) o; + return Objects.equals(this.category, monitorAsset.category) + && Objects.equals(this.name, monitorAsset.name) + && Objects.equals(this.resourceKey, monitorAsset.resourceKey) + && Objects.equals(this.resourceType, monitorAsset.resourceType) + && Objects.equals(this.url, monitorAsset.url) + && Objects.equals(this.additionalProperties, monitorAsset.additionalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(category, name, resourceKey, resourceType, url, additionalProperties); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MonitorAsset {\n"); + sb.append(" category: ").append(toIndentedString(category)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" resourceKey: ").append(toIndentedString(resourceKey)).append("\n"); + sb.append(" resourceType: ").append(toIndentedString(resourceType)).append("\n"); + sb.append(" url: ").append(toIndentedString(url)).append("\n"); + sb.append(" additionalProperties: ") + .append(toIndentedString(additionalProperties)) + .append("\n"); + sb.append('}'); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/MonitorAssetCategory.java b/src/main/java/com/datadog/api/client/v1/model/MonitorAssetCategory.java new file mode 100644 index 00000000000..2e11792a6d2 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/MonitorAssetCategory.java @@ -0,0 +1,54 @@ +/* + * 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.datadog.api.client.ModelEnum; +import com.fasterxml.jackson.annotation.JsonCreator; +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.Set; + +/** Indicates the type of asset this entity represents on a monitor. */ +@JsonSerialize(using = MonitorAssetCategory.MonitorAssetCategorySerializer.class) +public class MonitorAssetCategory extends ModelEnum { + + private static final Set allowedValues = new HashSet(Arrays.asList("runbook")); + + public static final MonitorAssetCategory RUNBOOK = new MonitorAssetCategory("runbook"); + + MonitorAssetCategory(String value) { + super(value, allowedValues); + } + + public static class MonitorAssetCategorySerializer extends StdSerializer { + public MonitorAssetCategorySerializer(Class t) { + super(t); + } + + public MonitorAssetCategorySerializer() { + this(null); + } + + @Override + public void serialize( + MonitorAssetCategory value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.value); + } + } + + @JsonCreator + public static MonitorAssetCategory fromValue(String value) { + return new MonitorAssetCategory(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/MonitorAssetResourceType.java b/src/main/java/com/datadog/api/client/v1/model/MonitorAssetResourceType.java new file mode 100644 index 00000000000..aa5c34d7dd0 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/MonitorAssetResourceType.java @@ -0,0 +1,55 @@ +/* + * 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.datadog.api.client.ModelEnum; +import com.fasterxml.jackson.annotation.JsonCreator; +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.Set; + +/** Type of internal Datadog resource associated with a monitor asset. */ +@JsonSerialize(using = MonitorAssetResourceType.MonitorAssetResourceTypeSerializer.class) +public class MonitorAssetResourceType extends ModelEnum { + + private static final Set allowedValues = new HashSet(Arrays.asList("notebook")); + + public static final MonitorAssetResourceType NOTEBOOK = new MonitorAssetResourceType("notebook"); + + MonitorAssetResourceType(String value) { + super(value, allowedValues); + } + + public static class MonitorAssetResourceTypeSerializer + extends StdSerializer { + public MonitorAssetResourceTypeSerializer(Class t) { + super(t); + } + + public MonitorAssetResourceTypeSerializer() { + this(null); + } + + @Override + public void serialize( + MonitorAssetResourceType value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.value); + } + } + + @JsonCreator + public static MonitorAssetResourceType fromValue(String value) { + return new MonitorAssetResourceType(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/MonitorUpdateRequest.java b/src/main/java/com/datadog/api/client/v1/model/MonitorUpdateRequest.java index 9a968a10f41..911449e5923 100644 --- a/src/main/java/com/datadog/api/client/v1/model/MonitorUpdateRequest.java +++ b/src/main/java/com/datadog/api/client/v1/model/MonitorUpdateRequest.java @@ -22,6 +22,7 @@ /** Object describing a monitor update request. */ @JsonPropertyOrder({ + MonitorUpdateRequest.JSON_PROPERTY_ASSETS, MonitorUpdateRequest.JSON_PROPERTY_CREATED, MonitorUpdateRequest.JSON_PROPERTY_CREATOR, MonitorUpdateRequest.JSON_PROPERTY_DELETED, @@ -44,6 +45,9 @@ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") public class MonitorUpdateRequest { @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_ASSETS = "assets"; + private JsonNullable> assets = JsonNullable.>undefined(); + public static final String JSON_PROPERTY_CREATED = "created"; private OffsetDateTime created; @@ -95,6 +99,50 @@ public class MonitorUpdateRequest { public static final String JSON_PROPERTY_TYPE = "type"; private MonitorType type; + public MonitorUpdateRequest assets(List assets) { + this.assets = JsonNullable.>of(assets); + return this; + } + + public MonitorUpdateRequest addAssetsItem(MonitorAsset assetsItem) { + if (this.assets == null || !this.assets.isPresent()) { + this.assets = JsonNullable.>of(new ArrayList<>()); + } + try { + this.assets.get().add(assetsItem); + } catch (java.util.NoSuchElementException e) { + // this can never happen, as we make sure above that the value is present + } + return this; + } + + /** + * The list of monitor assets tied to a monitor, which represents key links for users to take + * action on monitor alerts (for example, runbooks). + * + * @return assets + */ + @jakarta.annotation.Nullable + @JsonIgnore + public List getAssets() { + return assets.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_ASSETS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable> getAssets_JsonNullable() { + return assets; + } + + @JsonProperty(JSON_PROPERTY_ASSETS) + public void setAssets_JsonNullable(JsonNullable> assets) { + this.assets = assets; + } + + public void setAssets(List assets) { + this.assets = JsonNullable.>of(assets); + } + /** * Timestamp of the monitor creation. * @@ -513,7 +561,8 @@ public boolean equals(Object o) { return false; } MonitorUpdateRequest monitorUpdateRequest = (MonitorUpdateRequest) o; - return Objects.equals(this.created, monitorUpdateRequest.created) + return Objects.equals(this.assets, monitorUpdateRequest.assets) + && Objects.equals(this.created, monitorUpdateRequest.created) && Objects.equals(this.creator, monitorUpdateRequest.creator) && Objects.equals(this.deleted, monitorUpdateRequest.deleted) && Objects.equals(this.draftStatus, monitorUpdateRequest.draftStatus) @@ -536,6 +585,7 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash( + assets, created, creator, deleted, @@ -560,6 +610,7 @@ public int hashCode() { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class MonitorUpdateRequest {\n"); + sb.append(" assets: ").append(toIndentedString(assets)).append("\n"); sb.append(" created: ").append(toIndentedString(created)).append("\n"); sb.append(" creator: ").append(toIndentedString(creator)).append("\n"); sb.append(" deleted: ").append(toIndentedString(deleted)).append("\n"); diff --git a/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.freeze b/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.freeze index 2dbbd94e287..9dda83bd1cf 100644 --- a/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.freeze +++ b/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.freeze @@ -1 +1 @@ -2024-10-10T16:41:03.364Z \ No newline at end of file +2025-11-21T18:03:25.715Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.json b/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.json index b635739eee4..e2e99bfed86 100644 --- a/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.json +++ b/src/test/resources/cassettes/features/v1/Check_if_a_monitor_can_be_deleted_returns_OK_response.json @@ -3,7 +3,7 @@ "httpRequest": { "body": { "type": "JSON", - "json": "{\"message\": \"some message Notify: @hipchat-channel\", \"name\": \"Test-Check_if_a_monitor_can_be_deleted_returns_OK_response-1728578463\", \"options\": {\"enable_logs_sample\": true, \"escalation_message\": \"the situation has escalated\", \"evaluation_delay\": 700, \"include_tags\": true, \"locked\": false, \"new_host_delay\": 600, \"no_data_timeframe\": null, \"notification_preset_name\": \"hide_handles\", \"notify_audit\": false, \"notify_no_data\": false, \"on_missing_data\": \"show_and_notify_no_data\", \"renotify_interval\": 60, \"require_full_window\": true, \"thresholds\": {\"critical\": 2, \"warning\": 1}, \"timeout_h\": 24}, \"priority\": 3, \"query\": \"logs(\\\"service:foo AND type:error\\\").index(\\\"main\\\").rollup(\\\"count\\\").by(\\\"source\\\").last(\\\"5m\\\") > 2\", \"tags\": [\"test:testcheckifamonitorcanbedeletedreturnsokresponse1728578463\", \"env:ci\"], \"type\": \"log alert\"}" + "json": "{\"message\": \"some message Notify: @hipchat-channel\", \"name\": \"Test-Check_if_a_monitor_can_be_deleted_returns_OK_response-1763748205\", \"options\": {\"enable_logs_sample\": true, \"escalation_message\": \"the situation has escalated\", \"evaluation_delay\": 700, \"include_tags\": true, \"locked\": false, \"new_host_delay\": 600, \"no_data_timeframe\": null, \"notification_preset_name\": \"hide_handles\", \"notify_audit\": false, \"notify_no_data\": false, \"on_missing_data\": \"show_and_notify_no_data\", \"renotify_interval\": 60, \"require_full_window\": true, \"thresholds\": {\"critical\": 2, \"warning\": 1}, \"timeout_h\": 24}, \"priority\": 3, \"query\": \"logs(\\\"service:foo AND type:error\\\").index(\\\"main\\\").rollup(\\\"count\\\").by(\\\"source\\\").last(\\\"5m\\\") > 2\", \"tags\": [\"test:testcheckifamonitorcanbedeletedreturnsokresponse1763748205\", \"env:ci\"], \"type\": \"log alert\"}" }, "headers": {}, "method": "POST", @@ -12,7 +12,7 @@ "secure": true }, "httpResponse": { - "body": "{\"id\":155845287,\"org_id\":321813,\"type\":\"log alert\",\"name\":\"Test-Check_if_a_monitor_can_be_deleted_returns_OK_response-1728578463\",\"message\":\"some message Notify: @hipchat-channel\",\"tags\":[\"test:testcheckifamonitorcanbedeletedreturnsokresponse1728578463\",\"env:ci\"],\"query\":\"logs(\\\"service:foo AND type:error\\\").index(\\\"main\\\").rollup(\\\"count\\\").by(\\\"source\\\").last(\\\"5m\\\") > 2\",\"options\":{\"enable_logs_sample\":true,\"escalation_message\":\"the situation has escalated\",\"evaluation_delay\":700,\"include_tags\":true,\"locked\":false,\"new_host_delay\":600,\"no_data_timeframe\":null,\"notification_preset_name\":\"hide_handles\",\"notify_audit\":false,\"notify_no_data\":false,\"on_missing_data\":\"show_and_notify_no_data\",\"renotify_interval\":60,\"require_full_window\":true,\"thresholds\":{\"critical\":2.0,\"warning\":1.0},\"timeout_h\":24,\"groupby_simple_monitor\":false,\"silenced\":{}},\"multi\":true,\"created_at\":1728578463000,\"created\":\"2024-10-10T16:41:03.666877+00:00\",\"modified\":\"2024-10-10T16:41:03.666877+00:00\",\"deleted\":null,\"restricted_roles\":null,\"priority\":3,\"restriction_policy\":null,\"overall_state_modified\":null,\"overall_state\":\"No Data\",\"creator\":{\"name\":null,\"handle\":\"frog@datadoghq.com\",\"email\":\"frog@datadoghq.com\",\"id\":1445416}}\n", + "body": "{\"id\":238669218,\"org_id\":197728,\"type\":\"log alert\",\"name\":\"Test-Check_if_a_monitor_can_be_deleted_returns_OK_response-1763748205\",\"message\":\"some message Notify: @hipchat-channel\",\"tags\":[\"test:testcheckifamonitorcanbedeletedreturnsokresponse1763748205\",\"env:ci\"],\"query\":\"logs(\\\"service:foo AND type:error\\\").index(\\\"main\\\").rollup(\\\"count\\\").by(\\\"source\\\").last(\\\"5m\\\") > 2\",\"options\":{\"enable_logs_sample\":true,\"escalation_message\":\"the situation has escalated\",\"evaluation_delay\":700,\"include_tags\":true,\"locked\":false,\"new_host_delay\":600,\"no_data_timeframe\":null,\"notification_preset_name\":\"hide_handles\",\"notify_audit\":false,\"notify_no_data\":false,\"on_missing_data\":\"show_and_notify_no_data\",\"renotify_interval\":60,\"require_full_window\":true,\"thresholds\":{\"critical\":2.0,\"warning\":1.0},\"timeout_h\":24,\"groupby_simple_monitor\":false,\"silenced\":{}},\"multi\":true,\"created_at\":1763748206000,\"created\":\"2025-11-21T18:03:26.123200+00:00\",\"modified\":\"2025-11-21T18:03:26.123200+00:00\",\"deleted\":null,\"priority\":3,\"restricted_roles\":null,\"restriction_policy\":null,\"draft_status\":\"published\",\"assets\":[],\"overall_state_modified\":null,\"overall_state\":\"No Data\",\"creator\":{\"name\":\"Kevin Pombo\",\"handle\":\"kevin.pombo@datadoghq.com\",\"email\":\"kevin.pombo@datadoghq.com\",\"id\":25712273}}\n", "headers": { "Content-Type": [ "application/json" @@ -27,7 +27,7 @@ "timeToLive": { "unlimited": true }, - "id": "62c1e3de-fa62-bf48-1b4b-4353145ae62f" + "id": "64369370-ce78-9bf7-0440-a5c00ccb482e" }, { "httpRequest": { @@ -36,14 +36,14 @@ "path": "/api/v1/monitor/can_delete", "queryStringParameters": { "monitor_ids": [ - "155845287" + "238669218" ] }, "keepAlive": false, "secure": true }, "httpResponse": { - "body": "{\"data\":{\"ok\":[155845287]},\"errors\":null}\n", + "body": "{\"data\":{\"ok\":[238669218]},\"errors\":null}\n", "headers": { "Content-Type": [ "application/json" @@ -58,18 +58,18 @@ "timeToLive": { "unlimited": true }, - "id": "fe8eb621-0988-4b2c-2e0c-a4de081e1292" + "id": "b910a25a-9bfd-243a-e785-136906d2686b" }, { "httpRequest": { "headers": {}, "method": "DELETE", - "path": "/api/v1/monitor/155845287", + "path": "/api/v1/monitor/238669218", "keepAlive": false, "secure": true }, "httpResponse": { - "body": "{\"deleted_monitor_id\":155845287}\n", + "body": "{\"deleted_monitor_id\":238669218}\n", "headers": { "Content-Type": [ "application/json" @@ -84,6 +84,6 @@ "timeToLive": { "unlimited": true }, - "id": "7b83b1db-cc7a-0c77-8618-976742a2bf71" + "id": "15cac4bb-0036-071d-d3bb-e58080377ecc" } ] \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v1/Create_a_monitor_with_assets_returns_OK_response.freeze b/src/test/resources/cassettes/features/v1/Create_a_monitor_with_assets_returns_OK_response.freeze new file mode 100644 index 00000000000..12b1e5fed0c --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_monitor_with_assets_returns_OK_response.freeze @@ -0,0 +1 @@ +2025-11-21T19:04:55.769Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v1/Create_a_monitor_with_assets_returns_OK_response.json b/src/test/resources/cassettes/features/v1/Create_a_monitor_with_assets_returns_OK_response.json new file mode 100644 index 00000000000..9b9e6706036 --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_monitor_with_assets_returns_OK_response.json @@ -0,0 +1,58 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"assets\": [{\"category\": \"runbook\", \"name\": \"Monitor Runbook\", \"resource_key\": \"12345\", \"resource_type\": \"notebook\", \"url\": \"/notebooks/12345\"}], \"message\": \"some message Notify: @hipchat-channel\", \"name\": \"Test-Create_a_monitor_with_assets_returns_OK_response-1763751895\", \"options\": {\"scheduling_options\": {\"evaluation_window\": {\"day_starts\": \"04:00\", \"month_starts\": 1}}, \"thresholds\": {\"critical\": 0.5}}, \"query\": \"avg(current_1mo):avg:system.load.5{*} > 0.5\", \"type\": \"metric alert\"}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v1/monitor", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"id\":238681257,\"org_id\":321813,\"type\":\"query alert\",\"name\":\"Test-Create_a_monitor_with_assets_returns_OK_response-1763751895\",\"message\":\"some message Notify: @hipchat-channel\",\"tags\":[],\"query\":\"avg(current_1mo):avg:system.load.5{*} > 0.5\",\"options\":{\"scheduling_options\":{\"evaluation_window\":{\"day_starts\":\"04:00\",\"month_starts\":1}},\"thresholds\":{\"critical\":0.5},\"notify_no_data\":false,\"notify_audit\":false,\"new_host_delay\":300,\"include_tags\":true,\"silenced\":{}},\"multi\":false,\"created_at\":1763751896000,\"created\":\"2025-11-21T19:04:56.060346+00:00\",\"modified\":\"2025-11-21T19:04:56.060346+00:00\",\"deleted\":null,\"priority\":null,\"restricted_roles\":null,\"restriction_policy\":null,\"draft_status\":\"published\",\"assets\":[{\"monitor_id\":238681257,\"name\":\"Monitor Runbook\",\"category\":\"runbook\",\"url\":\"/notebooks/12345\",\"template_variables\":{},\"options\":{},\"resource_key\":\"12345\",\"resource_type\":\"notebook\"}],\"overall_state_modified\":null,\"overall_state\":\"No Data\",\"creator\":{\"name\":\"CI Account\",\"handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"email\":\"team-intg-tools-libs-spam@datadoghq.com\",\"id\":2320499}}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "ec3506ee-213b-45ef-4679-b54a52344b5e" + }, + { + "httpRequest": { + "headers": {}, + "method": "DELETE", + "path": "/api/v1/monitor/238681257", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"deleted_monitor_id\":238681257}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "f18e695b-1d8f-a348-c5c0-1a0547585bd4" + } +] \ No newline at end of file diff --git a/src/test/resources/com/datadog/api/client/v1/api/monitors.feature b/src/test/resources/com/datadog/api/client/v1/api/monitors.feature index 64e72f698b4..75a681927b9 100644 --- a/src/test/resources/com/datadog/api/client/v1/api/monitors.feature +++ b/src/test/resources/com/datadog/api/client/v1/api/monitors.feature @@ -131,6 +131,18 @@ Feature: Monitors And the response "type" is equal to "log alert" And the response "query" is equal to "logs(\"service:foo AND type:error\").index(\"main\").rollup(\"count\").by(\"source\").last(\"5m\") > 2" + @team:DataDog/monitor-app + Scenario: Create a monitor with assets returns "OK" response + Given new "CreateMonitor" request + And body with value {"assets": [{"category": "runbook", "name": "Monitor Runbook", "resource_key": "12345", "resource_type": "notebook", "url": "/notebooks/12345"}], "name": "{{ unique }}", "type": "metric alert", "query": "avg(current_1mo):avg:system.load.5{*} > 0.5", "message": "some message Notify: @hipchat-channel", "options":{"thresholds":{"critical":0.5}, "scheduling_options":{"evaluation_window":{"day_starts":"04:00", "month_starts":1}}}} + When the request is sent + Then the response status is 200 OK + And the response "assets[0].category" is equal to "runbook" + And the response "assets[0].name" is equal to "Monitor Runbook" + And the response "assets[0].resource_key" is equal to "12345" + And the response "assets[0].resource_type" is equal to "notebook" + And the response "assets[0].url" is equal to "/notebooks/12345" + @team:DataDog/monitor-app Scenario: Create an Error Tracking monitor returns "OK" response Given new "CreateMonitor" request @@ -169,7 +181,7 @@ Feature: Monitors Scenario: Edit a monitor returns "Bad Request" response Given new "UpdateMonitor" request And request contains "monitor_id" parameter from "REPLACE.ME" - And body with value {"draft_status": "published", "options": {"evaluation_delay": null, "include_tags": true, "min_failure_duration": 0, "min_location_failed": 1, "new_group_delay": null, "new_host_delay": 300, "no_data_timeframe": null, "notification_preset_name": "show_all", "notify_audit": false, "notify_by": [], "on_missing_data": "default", "renotify_interval": null, "renotify_occurrences": null, "renotify_statuses": ["alert"], "scheduling_options": {"custom_schedule": {"recurrences": [{"rrule": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR", "start": "2023-08-31T16:30:00", "timezone": "Europe/Paris"}]}, "evaluation_window": {"day_starts": "04:00", "hour_starts": 0, "month_starts": 1, "timezone": "Europe/Paris"}}, "synthetics_check_id": null, "threshold_windows": {"recovery_window": null, "trigger_window": null}, "thresholds": {"critical_recovery": null, "ok": null, "unknown": null, "warning": null, "warning_recovery": null}, "timeout_h": null, "variables": [{"compute": {"aggregation": "avg", "interval": 60000, "metric": "@duration"}, "data_source": "rum", "group_by": [{"facet": "status", "limit": 10, "sort": {"aggregation": "avg", "order": "desc"}}], "indexes": ["days-3", "days-7"], "name": "query_errors", "search": {"query": "service:query"}}]}, "priority": null, "restricted_roles": [], "tags": [], "type": "query alert"} + And body with value {"assets": [{"category": "runbook", "name": "Monitor Runbook", "resource_key": "12345", "resource_type": "notebook", "url": "/notebooks/12345"}], "draft_status": "published", "options": {"evaluation_delay": null, "include_tags": true, "min_failure_duration": 0, "min_location_failed": 1, "new_group_delay": null, "new_host_delay": 300, "no_data_timeframe": null, "notification_preset_name": "show_all", "notify_audit": false, "notify_by": [], "on_missing_data": "default", "renotify_interval": null, "renotify_occurrences": null, "renotify_statuses": ["alert"], "scheduling_options": {"custom_schedule": {"recurrences": [{"rrule": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR", "start": "2023-08-31T16:30:00", "timezone": "Europe/Paris"}]}, "evaluation_window": {"day_starts": "04:00", "hour_starts": 0, "month_starts": 1, "timezone": "Europe/Paris"}}, "synthetics_check_id": null, "threshold_windows": {"recovery_window": null, "trigger_window": null}, "thresholds": {"critical_recovery": null, "ok": null, "unknown": null, "warning": null, "warning_recovery": null}, "timeout_h": null, "variables": [{"compute": {"aggregation": "avg", "interval": 60000, "metric": "@duration"}, "data_source": "rum", "group_by": [{"facet": "status", "limit": 10, "sort": {"aggregation": "avg", "order": "desc"}}], "indexes": ["days-3", "days-7"], "name": "query_errors", "search": {"query": "service:query"}}]}, "priority": null, "restricted_roles": [], "tags": [], "type": "query alert"} When the request is sent Then the response status is 400 Bad Request