diff --git a/.apigentools-info b/.apigentools-info index 6f711ef2615..d34e756b3aa 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.4", - "regenerated": "2022-09-09 15:07:30.419474", - "spec_repo_commit": "0bdea812" + "regenerated": "2022-09-12 15:21:58.844978", + "spec_repo_commit": "dcd92077" }, "v2": { "apigentools_version": "1.6.4", - "regenerated": "2022-09-09 15:07:30.431613", - "spec_repo_commit": "0bdea812" + "regenerated": "2022-09-12 15:21:58.858643", + "spec_repo_commit": "dcd92077" } } } \ No newline at end of file diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index c68593f135f..d05b721d695 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -13380,6 +13380,91 @@ components: style: $ref: '#/components/schemas/WidgetRequestStyle' type: object + TopologyMapWidgetDefinition: + description: This widget displays a topology of nodes and edges for different + data sources. It replaces the service map widget. + properties: + custom_links: + description: List of custom links. + items: + $ref: '#/components/schemas/WidgetCustomLink' + type: array + requests: + description: One or more Topology requests. + items: + $ref: '#/components/schemas/TopologyRequest' + minItems: 1 + type: array + title: + description: Title of your widget. + type: string + title_align: + $ref: '#/components/schemas/WidgetTextAlign' + title_size: + description: Size of the title. + type: string + type: + $ref: '#/components/schemas/TopologyMapWidgetDefinitionType' + required: + - type + - requests + type: object + TopologyMapWidgetDefinitionType: + default: topology_map + description: Type of the topology map widget. + enum: + - topology_map + example: topology_map + type: string + x-enum-varnames: + - TOPOLOGY_MAP + TopologyQuery: + description: Query to service-based topology data sources like the service map + or data streams. + properties: + data_source: + $ref: '#/components/schemas/TopologyQueryDataSource' + filters: + description: Your environment and primary tag (or * if enabled for your + account). + example: + - env:prod + - az:us-east + items: + description: Environment or primary tag, generally in a key:value format + type: string + minItems: 1 + type: array + service: + description: Name of the service + example: myService + type: string + type: object + TopologyQueryDataSource: + description: Name of the data source + enum: + - data_streams + - service_map + type: string + x-enum-varnames: + - DATA_STREAMS + - SERVICE_MAP + TopologyRequest: + description: Request that will return nodes and edges to be used by topology + map. + properties: + query: + $ref: '#/components/schemas/TopologyQuery' + request_type: + $ref: '#/components/schemas/TopologyRequestType' + type: object + TopologyRequestType: + description: Widget request type. + enum: + - topology + type: string + x-enum-varnames: + - TOPOLOGY TreeMapColorBy: default: user deprecated: true @@ -16916,6 +17001,7 @@ components: - $ref: '#/components/schemas/TreeMapWidgetDefinition' - $ref: '#/components/schemas/ListStreamWidgetDefinition' - $ref: '#/components/schemas/FunnelWidgetDefinition' + - $ref: '#/components/schemas/TopologyMapWidgetDefinition' type: object WidgetDisplayType: description: Type of display to use for the request. diff --git a/examples/v1/dashboards/CreateDashboard_2652180930.java b/examples/v1/dashboards/CreateDashboard_2652180930.java new file mode 100644 index 00000000000..802bf37d72b --- /dev/null +++ b/examples/v1/dashboards/CreateDashboard_2652180930.java @@ -0,0 +1,67 @@ +// Create a new dashboard with topology_map widget + +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.Dashboard; +import com.datadog.api.client.v1.model.DashboardLayoutType; +import com.datadog.api.client.v1.model.TopologyMapWidgetDefinition; +import com.datadog.api.client.v1.model.TopologyMapWidgetDefinitionType; +import com.datadog.api.client.v1.model.TopologyQuery; +import com.datadog.api.client.v1.model.TopologyQueryDataSource; +import com.datadog.api.client.v1.model.TopologyRequest; +import com.datadog.api.client.v1.model.TopologyRequestType; +import com.datadog.api.client.v1.model.Widget; +import com.datadog.api.client.v1.model.WidgetDefinition; +import com.datadog.api.client.v1.model.WidgetLayout; +import com.datadog.api.client.v1.model.WidgetTextAlign; +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); + + Dashboard body = + new Dashboard() + .title("Example-Create_a_new_dashboard_with_topology_map_widget") + .description("") + .widgets( + Collections.singletonList( + new Widget() + .layout(new WidgetLayout().x(0L).y(0L).width(47L).height(15L)) + .definition( + new WidgetDefinition( + new TopologyMapWidgetDefinition() + .title("") + .titleSize("16") + .titleAlign(WidgetTextAlign.LEFT) + .type(TopologyMapWidgetDefinitionType.TOPOLOGY_MAP) + .requests( + Collections.singletonList( + new TopologyRequest() + .requestType(TopologyRequestType.TOPOLOGY) + .query( + new TopologyQuery() + .dataSource( + TopologyQueryDataSource.SERVICE_MAP) + .service("") + .filters( + Arrays.asList( + "env:none", "environment:*"))))))))) + .layoutType(DashboardLayoutType.FREE) + .isReadOnly(false); + + 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/TopologyMapWidgetDefinition.java b/src/main/java/com/datadog/api/client/v1/model/TopologyMapWidgetDefinition.java new file mode 100644 index 00000000000..db94b7202fb --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/TopologyMapWidgetDefinition.java @@ -0,0 +1,263 @@ +/* + * 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; + +/** + * This widget displays a topology of nodes and edges for different data sources. It replaces the + * service map widget. + */ +@JsonPropertyOrder({ + TopologyMapWidgetDefinition.JSON_PROPERTY_CUSTOM_LINKS, + TopologyMapWidgetDefinition.JSON_PROPERTY_REQUESTS, + TopologyMapWidgetDefinition.JSON_PROPERTY_TITLE, + TopologyMapWidgetDefinition.JSON_PROPERTY_TITLE_ALIGN, + TopologyMapWidgetDefinition.JSON_PROPERTY_TITLE_SIZE, + TopologyMapWidgetDefinition.JSON_PROPERTY_TYPE +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class TopologyMapWidgetDefinition { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_CUSTOM_LINKS = "custom_links"; + private List customLinks = null; + + public static final String JSON_PROPERTY_REQUESTS = "requests"; + private List requests = new ArrayList<>(); + + public static final String JSON_PROPERTY_TITLE = "title"; + private String title; + + public static final String JSON_PROPERTY_TITLE_ALIGN = "title_align"; + private WidgetTextAlign titleAlign; + + public static final String JSON_PROPERTY_TITLE_SIZE = "title_size"; + private String titleSize; + + public static final String JSON_PROPERTY_TYPE = "type"; + private TopologyMapWidgetDefinitionType type = TopologyMapWidgetDefinitionType.TOPOLOGY_MAP; + + public TopologyMapWidgetDefinition() {} + + @JsonCreator + public TopologyMapWidgetDefinition( + @JsonProperty(required = true, value = JSON_PROPERTY_REQUESTS) List requests, + @JsonProperty(required = true, value = JSON_PROPERTY_TYPE) + TopologyMapWidgetDefinitionType type) { + this.requests = requests; + this.type = type; + this.unparsed |= !type.isValid(); + } + + public TopologyMapWidgetDefinition customLinks(List customLinks) { + this.customLinks = customLinks; + for (WidgetCustomLink item : customLinks) { + this.unparsed |= item.unparsed; + } + return this; + } + + public TopologyMapWidgetDefinition addCustomLinksItem(WidgetCustomLink customLinksItem) { + if (this.customLinks == null) { + this.customLinks = new ArrayList<>(); + } + this.customLinks.add(customLinksItem); + this.unparsed |= customLinksItem.unparsed; + return this; + } + + /** + * List of custom links. + * + * @return customLinks + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_CUSTOM_LINKS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getCustomLinks() { + return customLinks; + } + + public void setCustomLinks(List customLinks) { + this.customLinks = customLinks; + } + + public TopologyMapWidgetDefinition requests(List requests) { + this.requests = requests; + for (TopologyRequest item : requests) { + this.unparsed |= item.unparsed; + } + return this; + } + + public TopologyMapWidgetDefinition addRequestsItem(TopologyRequest requestsItem) { + this.requests.add(requestsItem); + this.unparsed |= requestsItem.unparsed; + return this; + } + + /** + * One or more Topology requests. + * + * @return requests + */ + @JsonProperty(JSON_PROPERTY_REQUESTS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getRequests() { + return requests; + } + + public void setRequests(List requests) { + this.requests = requests; + } + + public TopologyMapWidgetDefinition title(String title) { + this.title = title; + return this; + } + + /** + * Title of your widget. + * + * @return title + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_TITLE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public TopologyMapWidgetDefinition titleAlign(WidgetTextAlign titleAlign) { + this.titleAlign = titleAlign; + this.unparsed |= !titleAlign.isValid(); + return this; + } + + /** + * How to align the text on the widget. + * + * @return titleAlign + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_TITLE_ALIGN) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public WidgetTextAlign getTitleAlign() { + return titleAlign; + } + + public void setTitleAlign(WidgetTextAlign titleAlign) { + if (!titleAlign.isValid()) { + this.unparsed = true; + } + this.titleAlign = titleAlign; + } + + public TopologyMapWidgetDefinition titleSize(String titleSize) { + this.titleSize = titleSize; + return this; + } + + /** + * Size of the title. + * + * @return titleSize + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_TITLE_SIZE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getTitleSize() { + return titleSize; + } + + public void setTitleSize(String titleSize) { + this.titleSize = titleSize; + } + + public TopologyMapWidgetDefinition type(TopologyMapWidgetDefinitionType type) { + this.type = type; + this.unparsed |= !type.isValid(); + return this; + } + + /** + * Type of the topology map widget. + * + * @return type + */ + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public TopologyMapWidgetDefinitionType getType() { + return type; + } + + public void setType(TopologyMapWidgetDefinitionType type) { + if (!type.isValid()) { + this.unparsed = true; + } + this.type = type; + } + + /** Return true if this TopologyMapWidgetDefinition object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TopologyMapWidgetDefinition topologyMapWidgetDefinition = (TopologyMapWidgetDefinition) o; + return Objects.equals(this.customLinks, topologyMapWidgetDefinition.customLinks) + && Objects.equals(this.requests, topologyMapWidgetDefinition.requests) + && Objects.equals(this.title, topologyMapWidgetDefinition.title) + && Objects.equals(this.titleAlign, topologyMapWidgetDefinition.titleAlign) + && Objects.equals(this.titleSize, topologyMapWidgetDefinition.titleSize) + && Objects.equals(this.type, topologyMapWidgetDefinition.type); + } + + @Override + public int hashCode() { + return Objects.hash(customLinks, requests, title, titleAlign, titleSize, type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TopologyMapWidgetDefinition {\n"); + sb.append(" customLinks: ").append(toIndentedString(customLinks)).append("\n"); + sb.append(" requests: ").append(toIndentedString(requests)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" titleAlign: ").append(toIndentedString(titleAlign)).append("\n"); + sb.append(" titleSize: ").append(toIndentedString(titleSize)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).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/TopologyMapWidgetDefinitionType.java b/src/main/java/com/datadog/api/client/v1/model/TopologyMapWidgetDefinitionType.java new file mode 100644 index 00000000000..90f841a1ba9 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/TopologyMapWidgetDefinitionType.java @@ -0,0 +1,96 @@ +/* + * 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; + +/** Type of the topology map widget. */ +@JsonSerialize( + using = TopologyMapWidgetDefinitionType.TopologyMapWidgetDefinitionTypeSerializer.class) +public class TopologyMapWidgetDefinitionType { + + public static final TopologyMapWidgetDefinitionType TOPOLOGY_MAP = + new TopologyMapWidgetDefinitionType("topology_map"); + + private static final Set allowedValues = + new HashSet(Arrays.asList("topology_map")); + + private String value; + + public boolean isValid() { + return allowedValues.contains(this.value); + } + + TopologyMapWidgetDefinitionType(String value) { + this.value = value; + } + + public static class TopologyMapWidgetDefinitionTypeSerializer + extends StdSerializer { + public TopologyMapWidgetDefinitionTypeSerializer(Class t) { + super(t); + } + + public TopologyMapWidgetDefinitionTypeSerializer() { + this(null); + } + + @Override + public void serialize( + TopologyMapWidgetDefinitionType 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 TopologyMapWidgetDefinitionType 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(((TopologyMapWidgetDefinitionType) o).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TopologyMapWidgetDefinitionType fromValue(String value) { + return new TopologyMapWidgetDefinitionType(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/TopologyQuery.java b/src/main/java/com/datadog/api/client/v1/model/TopologyQuery.java new file mode 100644 index 00000000000..b40e185d08a --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/TopologyQuery.java @@ -0,0 +1,151 @@ +/* + * 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.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; + +/** Query to service-based topology data sources like the service map or data streams. */ +@JsonPropertyOrder({ + TopologyQuery.JSON_PROPERTY_DATA_SOURCE, + TopologyQuery.JSON_PROPERTY_FILTERS, + TopologyQuery.JSON_PROPERTY_SERVICE +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class TopologyQuery { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_DATA_SOURCE = "data_source"; + private TopologyQueryDataSource dataSource; + + public static final String JSON_PROPERTY_FILTERS = "filters"; + private List filters = null; + + public static final String JSON_PROPERTY_SERVICE = "service"; + private String service; + + public TopologyQuery dataSource(TopologyQueryDataSource dataSource) { + this.dataSource = dataSource; + this.unparsed |= !dataSource.isValid(); + return this; + } + + /** + * Name of the data source + * + * @return dataSource + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_DATA_SOURCE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public TopologyQueryDataSource getDataSource() { + return dataSource; + } + + public void setDataSource(TopologyQueryDataSource dataSource) { + if (!dataSource.isValid()) { + this.unparsed = true; + } + this.dataSource = dataSource; + } + + public TopologyQuery filters(List filters) { + this.filters = filters; + return this; + } + + public TopologyQuery addFiltersItem(String filtersItem) { + if (this.filters == null) { + this.filters = new ArrayList<>(); + } + this.filters.add(filtersItem); + return this; + } + + /** + * Your environment and primary tag (or * if enabled for your account). + * + * @return filters + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_FILTERS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getFilters() { + return filters; + } + + public void setFilters(List filters) { + this.filters = filters; + } + + public TopologyQuery service(String service) { + this.service = service; + return this; + } + + /** + * Name of the service + * + * @return service + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_SERVICE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + /** Return true if this TopologyQuery object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TopologyQuery topologyQuery = (TopologyQuery) o; + return Objects.equals(this.dataSource, topologyQuery.dataSource) + && Objects.equals(this.filters, topologyQuery.filters) + && Objects.equals(this.service, topologyQuery.service); + } + + @Override + public int hashCode() { + return Objects.hash(dataSource, filters, service); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TopologyQuery {\n"); + sb.append(" dataSource: ").append(toIndentedString(dataSource)).append("\n"); + sb.append(" filters: ").append(toIndentedString(filters)).append("\n"); + sb.append(" service: ").append(toIndentedString(service)).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/TopologyQueryDataSource.java b/src/main/java/com/datadog/api/client/v1/model/TopologyQueryDataSource.java new file mode 100644 index 00000000000..5de0f7de451 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/TopologyQueryDataSource.java @@ -0,0 +1,97 @@ +/* + * 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 data source */ +@JsonSerialize(using = TopologyQueryDataSource.TopologyQueryDataSourceSerializer.class) +public class TopologyQueryDataSource { + + public static final TopologyQueryDataSource DATA_STREAMS = + new TopologyQueryDataSource("data_streams"); + public static final TopologyQueryDataSource SERVICE_MAP = + new TopologyQueryDataSource("service_map"); + + private static final Set allowedValues = + new HashSet(Arrays.asList("data_streams", "service_map")); + + private String value; + + public boolean isValid() { + return allowedValues.contains(this.value); + } + + TopologyQueryDataSource(String value) { + this.value = value; + } + + public static class TopologyQueryDataSourceSerializer + extends StdSerializer { + public TopologyQueryDataSourceSerializer(Class t) { + super(t); + } + + public TopologyQueryDataSourceSerializer() { + this(null); + } + + @Override + public void serialize( + TopologyQueryDataSource 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 TopologyQueryDataSource 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(((TopologyQueryDataSource) o).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TopologyQueryDataSource fromValue(String value) { + return new TopologyQueryDataSource(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/TopologyRequest.java b/src/main/java/com/datadog/api/client/v1/model/TopologyRequest.java new file mode 100644 index 00000000000..7d77eaf3581 --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/TopologyRequest.java @@ -0,0 +1,115 @@ +/* + * 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.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.Objects; + +/** Request that will return nodes and edges to be used by topology map. */ +@JsonPropertyOrder({ + TopologyRequest.JSON_PROPERTY_QUERY, + TopologyRequest.JSON_PROPERTY_REQUEST_TYPE +}) +@jakarta.annotation.Generated( + value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator") +public class TopologyRequest { + @JsonIgnore public boolean unparsed = false; + public static final String JSON_PROPERTY_QUERY = "query"; + private TopologyQuery query; + + public static final String JSON_PROPERTY_REQUEST_TYPE = "request_type"; + private TopologyRequestType requestType; + + public TopologyRequest query(TopologyQuery query) { + this.query = query; + this.unparsed |= query.unparsed; + return this; + } + + /** + * Query to service-based topology data sources like the service map or data streams. + * + * @return query + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_QUERY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public TopologyQuery getQuery() { + return query; + } + + public void setQuery(TopologyQuery query) { + this.query = query; + } + + public TopologyRequest requestType(TopologyRequestType requestType) { + this.requestType = requestType; + this.unparsed |= !requestType.isValid(); + return this; + } + + /** + * Widget request type. + * + * @return requestType + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_REQUEST_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public TopologyRequestType getRequestType() { + return requestType; + } + + public void setRequestType(TopologyRequestType requestType) { + if (!requestType.isValid()) { + this.unparsed = true; + } + this.requestType = requestType; + } + + /** Return true if this TopologyRequest object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TopologyRequest topologyRequest = (TopologyRequest) o; + return Objects.equals(this.query, topologyRequest.query) + && Objects.equals(this.requestType, topologyRequest.requestType); + } + + @Override + public int hashCode() { + return Objects.hash(query, requestType); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TopologyRequest {\n"); + sb.append(" query: ").append(toIndentedString(query)).append("\n"); + sb.append(" requestType: ").append(toIndentedString(requestType)).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/TopologyRequestType.java b/src/main/java/com/datadog/api/client/v1/model/TopologyRequestType.java new file mode 100644 index 00000000000..15dca410c8c --- /dev/null +++ b/src/main/java/com/datadog/api/client/v1/model/TopologyRequestType.java @@ -0,0 +1,92 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.v1.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.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; + +/** Widget request type. */ +@JsonSerialize(using = TopologyRequestType.TopologyRequestTypeSerializer.class) +public class TopologyRequestType { + + public static final TopologyRequestType TOPOLOGY = new TopologyRequestType("topology"); + + private static final Set allowedValues = new HashSet(Arrays.asList("topology")); + + private String value; + + public boolean isValid() { + return allowedValues.contains(this.value); + } + + TopologyRequestType(String value) { + this.value = value; + } + + public static class TopologyRequestTypeSerializer extends StdSerializer { + public TopologyRequestTypeSerializer(Class t) { + super(t); + } + + public TopologyRequestTypeSerializer() { + this(null); + } + + @Override + public void serialize( + TopologyRequestType 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 TopologyRequestType 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(((TopologyRequestType) o).value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TopologyRequestType fromValue(String value) { + return new TopologyRequestType(value); + } +} diff --git a/src/main/java/com/datadog/api/client/v1/model/WidgetDefinition.java b/src/main/java/com/datadog/api/client/v1/model/WidgetDefinition.java index 12655d8a821..ac9e7e0a178 100644 --- a/src/main/java/com/datadog/api/client/v1/model/WidgetDefinition.java +++ b/src/main/java/com/datadog/api/client/v1/model/WidgetDefinition.java @@ -1383,6 +1383,51 @@ public WidgetDefinition deserialize(JsonParser jp, DeserializationContext ctxt) log.log(Level.FINER, "Input data does not match schema 'FunnelWidgetDefinition'", e); } + // deserialize TopologyMapWidgetDefinition + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (TopologyMapWidgetDefinition.class.equals(Integer.class) + || TopologyMapWidgetDefinition.class.equals(Long.class) + || TopologyMapWidgetDefinition.class.equals(Float.class) + || TopologyMapWidgetDefinition.class.equals(Double.class) + || TopologyMapWidgetDefinition.class.equals(Boolean.class) + || TopologyMapWidgetDefinition.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((TopologyMapWidgetDefinition.class.equals(Integer.class) + || TopologyMapWidgetDefinition.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((TopologyMapWidgetDefinition.class.equals(Float.class) + || TopologyMapWidgetDefinition.class.equals(Double.class)) + && (token == JsonToken.VALUE_NUMBER_FLOAT + || token == JsonToken.VALUE_NUMBER_INT)); + attemptParsing |= + (TopologyMapWidgetDefinition.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (TopologyMapWidgetDefinition.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + tmp = tree.traverse(jp.getCodec()).readValueAs(TopologyMapWidgetDefinition.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 (!((TopologyMapWidgetDefinition) tmp).unparsed) { + deserialized = tmp; + match++; + } + log.log(Level.FINER, "Input data matches schema 'TopologyMapWidgetDefinition'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'TopologyMapWidgetDefinition'", e); + } + WidgetDefinition ret = new WidgetDefinition(); if (match == 1) { ret.setActualInstance(deserialized); @@ -1556,6 +1601,11 @@ public WidgetDefinition(FunnelWidgetDefinition o) { setActualInstance(o); } + public WidgetDefinition(TopologyMapWidgetDefinition o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + static { schemas.put("AlertGraphWidgetDefinition", new GenericType() {}); schemas.put("AlertValueWidgetDefinition", new GenericType() {}); @@ -1589,6 +1639,7 @@ public WidgetDefinition(FunnelWidgetDefinition o) { schemas.put("TreeMapWidgetDefinition", new GenericType() {}); schemas.put("ListStreamWidgetDefinition", new GenericType() {}); schemas.put("FunnelWidgetDefinition", new GenericType() {}); + schemas.put("TopologyMapWidgetDefinition", new GenericType() {}); JSON.registerDescendants(WidgetDefinition.class, Collections.unmodifiableMap(schemas)); } @@ -1608,7 +1659,8 @@ public Map getSchemas() { * QueryValueWidgetDefinition, ScatterPlotWidgetDefinition, SLOWidgetDefinition, * ServiceMapWidgetDefinition, ServiceSummaryWidgetDefinition, SunburstWidgetDefinition, * TableWidgetDefinition, TimeseriesWidgetDefinition, ToplistWidgetDefinition, - * TreeMapWidgetDefinition, ListStreamWidgetDefinition, FunnelWidgetDefinition + * TreeMapWidgetDefinition, ListStreamWidgetDefinition, FunnelWidgetDefinition, + * TopologyMapWidgetDefinition * *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a * composed schema (allOf, anyOf, oneOf). @@ -1733,6 +1785,10 @@ public void setActualInstance(Object instance) { super.setActualInstance(instance); return; } + if (JSON.isInstanceOf(TopologyMapWidgetDefinition.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } if (JSON.isInstanceOf(UnparsedObject.class, instance, new HashSet>())) { super.setActualInstance(instance); @@ -1749,7 +1805,7 @@ public void setActualInstance(Object instance) { + " SLOWidgetDefinition, ServiceMapWidgetDefinition, ServiceSummaryWidgetDefinition," + " SunburstWidgetDefinition, TableWidgetDefinition, TimeseriesWidgetDefinition," + " ToplistWidgetDefinition, TreeMapWidgetDefinition, ListStreamWidgetDefinition," - + " FunnelWidgetDefinition"); + + " FunnelWidgetDefinition, TopologyMapWidgetDefinition"); } /** @@ -1763,7 +1819,7 @@ public void setActualInstance(Object instance) { * SLOWidgetDefinition, ServiceMapWidgetDefinition, ServiceSummaryWidgetDefinition, * SunburstWidgetDefinition, TableWidgetDefinition, TimeseriesWidgetDefinition, * ToplistWidgetDefinition, TreeMapWidgetDefinition, ListStreamWidgetDefinition, - * FunnelWidgetDefinition + * FunnelWidgetDefinition, TopologyMapWidgetDefinition * * @return The actual instance (AlertGraphWidgetDefinition, AlertValueWidgetDefinition, * ChangeWidgetDefinition, CheckStatusWidgetDefinition, DistributionWidgetDefinition, @@ -1774,7 +1830,8 @@ public void setActualInstance(Object instance) { * QueryValueWidgetDefinition, ScatterPlotWidgetDefinition, SLOWidgetDefinition, * ServiceMapWidgetDefinition, ServiceSummaryWidgetDefinition, SunburstWidgetDefinition, * TableWidgetDefinition, TimeseriesWidgetDefinition, ToplistWidgetDefinition, - * TreeMapWidgetDefinition, ListStreamWidgetDefinition, FunnelWidgetDefinition) + * TreeMapWidgetDefinition, ListStreamWidgetDefinition, FunnelWidgetDefinition, + * TopologyMapWidgetDefinition) */ @Override public Object getActualInstance() { @@ -2102,4 +2159,15 @@ public ListStreamWidgetDefinition getListStreamWidgetDefinition() throws ClassCa public FunnelWidgetDefinition getFunnelWidgetDefinition() throws ClassCastException { return (FunnelWidgetDefinition) super.getActualInstance(); } + + /** + * Get the actual instance of `TopologyMapWidgetDefinition`. If the actual instance is not + * `TopologyMapWidgetDefinition`, the ClassCastException will be thrown. + * + * @return The actual instance of `TopologyMapWidgetDefinition` + * @throws ClassCastException if the instance is not `TopologyMapWidgetDefinition` + */ + public TopologyMapWidgetDefinition getTopologyMapWidgetDefinition() throws ClassCastException { + return (TopologyMapWidgetDefinition) super.getActualInstance(); + } } diff --git a/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_topology_map_widget.freeze b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_topology_map_widget.freeze new file mode 100644 index 00000000000..32436c666f0 --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_topology_map_widget.freeze @@ -0,0 +1 @@ +2022-09-12T15:16:05.847Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_topology_map_widget.json b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_topology_map_widget.json new file mode 100644 index 00000000000..ea6f985ae71 --- /dev/null +++ b/src/test/resources/cassettes/features/v1/Create_a_new_dashboard_with_topology_map_widget.json @@ -0,0 +1,58 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"description\":\"\",\"is_read_only\":false,\"layout_type\":\"free\",\"notify_list\":[],\"template_variables\":[],\"title\":\"Test-Create_a_new_dashboard_with_topology_map_widget-1662995765\",\"widgets\":[{\"definition\":{\"requests\":[{\"query\":{\"data_source\":\"service_map\",\"filters\":[\"env:none\",\"environment:*\"],\"service\":\"\"},\"request_type\":\"topology\"}],\"title\":\"\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"topology_map\"},\"layout\":{\"height\":15,\"width\":47,\"x\":0,\"y\":0}}]}" + }, + "headers": {}, + "method": "POST", + "path": "/api/v1/dashboard", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"notify_list\":[],\"description\":\"\",\"restricted_roles\":[],\"author_name\":null,\"template_variables\":[],\"is_read_only\":false,\"id\":\"8mx-5gx-wjm\",\"title\":\"Test-Create_a_new_dashboard_with_topology_map_widget-1662995765\",\"url\":\"/dashboard/8mx-5gx-wjm/test-createanewdashboardwithtopologymapwidget-1662995765\",\"created_at\":\"2022-09-12T15:16:06.040625+00:00\",\"modified_at\":\"2022-09-12T15:16:06.040625+00:00\",\"author_handle\":\"frog@datadoghq.com\",\"widgets\":[{\"definition\":{\"type\":\"topology_map\",\"requests\":[{\"query\":{\"data_source\":\"service_map\",\"service\":\"\",\"filters\":[\"env:none\",\"environment:*\"]},\"request_type\":\"topology\"}],\"title_align\":\"left\",\"title_size\":\"16\",\"title\":\"\"},\"layout\":{\"y\":0,\"width\":47,\"x\":0,\"height\":15},\"id\":1383483616434400}],\"layout_type\":\"free\"}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "db23cdbb-bb3e-26b9-7a5b-c8091d9aef10" + }, + { + "httpRequest": { + "headers": {}, + "method": "DELETE", + "path": "/api/v1/dashboard/8mx-5gx-wjm", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "body": "{\"deleted_dashboard_id\":\"8mx-5gx-wjm\"}\n", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "statusCode": 200, + "reasonPhrase": "OK" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "d969104a-3036-2298-0232-2499a974f7ab" + } +] \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Get_a_list_of_metrics_with_configured_filter_returns_Success_response.json b/src/test/resources/cassettes/features/v2/Get_a_list_of_metrics_with_configured_filter_returns_Success_response.json index 8561d0d6691..f8991e17993 100644 --- a/src/test/resources/cassettes/features/v2/Get_a_list_of_metrics_with_configured_filter_returns_Success_response.json +++ b/src/test/resources/cassettes/features/v2/Get_a_list_of_metrics_with_configured_filter_returns_Success_response.json @@ -28,6 +28,6 @@ "timeToLive": { "unlimited": true }, - "id": "6a6c3737-1163-32b6-3162-f7d3bcb05a08" + "id": "6a6c3737-1163-32b6-3162-f7d3bcb05a07" } ] \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/List_tag_configurations_with_configured_filter_returns_Success_response.json b/src/test/resources/cassettes/features/v2/List_tag_configurations_with_configured_filter_returns_Success_response.json index ee34d264e57..5e8099f679a 100644 --- a/src/test/resources/cassettes/features/v2/List_tag_configurations_with_configured_filter_returns_Success_response.json +++ b/src/test/resources/cassettes/features/v2/List_tag_configurations_with_configured_filter_returns_Success_response.json @@ -28,6 +28,6 @@ "timeToLive": { "unlimited": true }, - "id": "6a6c3737-1163-32b6-3162-f7d3bcb05a07" + "id": "6a6c3737-1163-32b6-3162-f7d3bcb05a06" } ] \ 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 f9a90ee42c2..ef0406843d3 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 @@ -432,6 +432,18 @@ Feature: Dashboards Then the response status is 200 OK And the response "widgets[0].definition.type" is equal to "toplist" + @team:DataDog/dashboards + Scenario: Create a new dashboard with topology_map widget + Given new "CreateDashboard" request + And body from file "dashboards_json_payload/topology_map_widget.json" + When the request is sent + Then the response status is 200 OK + And the response "widgets[0].definition.type" is equal to "topology_map" + And the response "widgets[0].definition.requests[0].request_type" is equal to "topology" + And the response "widgets[0].definition.requests[0].query.data_source" is equal to "service_map" + And the response "widgets[0].definition.requests[0].query.service" is equal to "" + And the response "widgets[0].definition.requests[0].query.filters" is equal to ["env:none","environment:*"] + @team:DataDog/dashboards Scenario: Create a new dashboard with trace_service widget Given new "CreateDashboard" request diff --git a/src/test/resources/com/datadog/api/client/v1/api/dashboards_json_payload/topology_map_widget.json b/src/test/resources/com/datadog/api/client/v1/api/dashboards_json_payload/topology_map_widget.json new file mode 100644 index 00000000000..e3cf8835182 --- /dev/null +++ b/src/test/resources/com/datadog/api/client/v1/api/dashboards_json_payload/topology_map_widget.json @@ -0,0 +1,34 @@ +{ + "title": "{{ unique }}", + "description": "", + "widgets": [ + { + "layout": { + "x": 0, + "y": 0, + "width": 47, + "height": 15 + }, + "definition": { + "title": "", + "title_size": "16", + "title_align": "left", + "type": "topology_map", + "requests": [ + { + "request_type": "topology", + "query": { + "data_source": "service_map", + "service": "", + "filters": ["env:none", "environment:*"] + } + } + ] + } + } + ], + "template_variables": [], + "layout_type": "free", + "is_read_only": false, + "notify_list": [] +}