diff --git a/.generated-info b/.generated-info
index 10f41d902f8..bcc14741a70 100644
--- a/.generated-info
+++ b/.generated-info
@@ -1,4 +1,4 @@
{
- "spec_repo_commit": "d58cb84",
- "generated": "2025-08-22 18:46:36.195"
+ "spec_repo_commit": "205813d",
+ "generated": "2025-08-25 08:43:17.545"
}
diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml
index 997d4861896..123b5ff1561 100644
--- a/.generator/schemas/v2/openapi.yaml
+++ b/.generator/schemas/v2/openapi.yaml
@@ -9284,6 +9284,15 @@ components:
that evaluates to a boolean.
example: ${true}
type: string
+ ComponentRecommendation:
+ description: Resource recommendation for a single Spark component (driver or
+ executor). Contains estimation data used to patch Spark job specs.
+ properties:
+ estimation:
+ $ref: '#/components/schemas/Estimation'
+ required:
+ - estimation
+ type: object
ComponentType:
description: The UI component type.
enum:
@@ -10480,6 +10489,28 @@ components:
type: string
x-enum-varnames:
- COST_BY_ORG
+ Cpu:
+ description: CPU usage statistics derived from historical Spark job metrics.
+ Provides multiple estimates so users can choose between conservative and cost-saving
+ risk profiles.
+ properties:
+ max:
+ description: Maximum CPU usage observed for the job, expressed in millicores.
+ This represents the upper bound of usage.
+ format: int64
+ type: integer
+ p75:
+ description: 75th percentile of CPU usage (millicores). Represents a cost-saving
+ configuration while covering most workloads.
+ format: int64
+ type: integer
+ p95:
+ description: 95th percentile of CPU usage (millicores). Balances performance
+ and cost, providing a safer margin than p75.
+ format: int64
+ type: integer
+ type: object
+ x-model-simple-name: SpaCpu
CreateActionConnectionRequest:
description: Request used to create an action connection.
properties:
@@ -15937,6 +15968,33 @@ components:
type: string
x-enum-varnames:
- ESCALATION_POLICY_STEPS
+ Estimation:
+ description: Recommended resource values for a Spark driver or executor, derived
+ from recent real usage metrics. Used by SPA to propose more efficient pod
+ sizing.
+ properties:
+ cpu:
+ $ref: '#/components/schemas/Cpu'
+ ephemeral_storage:
+ description: Recommended ephemeral storage allocation (in MiB). Derived
+ from job temporary storage patterns.
+ format: int64
+ type: integer
+ heap:
+ description: Recommended JVM heap size (in MiB).
+ format: int64
+ type: integer
+ memory:
+ description: Recommended total memory allocation (in MiB). Includes both
+ heap and overhead.
+ format: int64
+ type: integer
+ overhead:
+ description: Recommended JVM overhead (in MiB). Computed as total memory
+ - heap.
+ format: int64
+ type: integer
+ type: object
Event:
description: The metadata associated with a request.
properties:
@@ -32835,6 +32893,52 @@ components:
x-enum-varnames:
- ANY
- ALL
+ RecommendationAttributes:
+ description: Attributes of the SPA Recommendation resource. Contains recommendations
+ for both driver and executor components.
+ properties:
+ driver:
+ $ref: '#/components/schemas/ComponentRecommendation'
+ executor:
+ $ref: '#/components/schemas/ComponentRecommendation'
+ required:
+ - driver
+ - executor
+ type: object
+ RecommendationData:
+ description: JSON:API resource object for SPA Recommendation. Includes type,
+ optional ID, and resource attributes with structured recommendations.
+ properties:
+ attributes:
+ $ref: '#/components/schemas/RecommendationAttributes'
+ id:
+ description: Resource identifier for the recommendation. Optional in responses.
+ type: string
+ type:
+ $ref: '#/components/schemas/RecommendationType'
+ required:
+ - type
+ - attributes
+ type: object
+ RecommendationDocument:
+ description: JSON:API document containing a single Recommendation resource.
+ Returned by SPA when the Spark Gateway requests recommendations.
+ properties:
+ data:
+ $ref: '#/components/schemas/RecommendationData'
+ required:
+ - data
+ type: object
+ RecommendationType:
+ default: recommendation
+ description: JSON:API resource type for Spark Pod Autosizing recommendations.
+ Identifies the Recommendation resource returned by SPA.
+ enum:
+ - recommendation
+ example: recommendation
+ type: string
+ x-enum-varnames:
+ - RECOMMENDATION
RegisterAppKeyResponse:
description: The response object after creating an app key registration.
properties:
@@ -65710,6 +65814,69 @@ paths:
x-unstable: '**Note**: This feature is in private beta. To request access, use
the request access form in the [Service Level Objectives](https://docs.datadoghq.com/service_management/service_level_objectives/#slo-csv-export)
docs.'
+ /api/v2/spa/recommendations/{service}/{shard}:
+ get:
+ description: Retrieve resource recommendations for a Spark job. The caller (Spark
+ Gateway or DJM UI) provides a service name and shard identifier, and SPA returns
+ structured recommendations for driver and executor resources.
+ operationId: GetSPARecommendations
+ parameters:
+ - description: The shard tag for a spark job, which differentiates jobs within
+ the same service that have different resource needs
+ in: path
+ name: shard
+ required: true
+ schema:
+ type: string
+ - description: The service name for a spark job
+ in: path
+ name: service
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ content:
+ application/json:
+ example:
+ data:
+ attributes:
+ driver:
+ estimation:
+ cpu:
+ max: 1500
+ p75: 1000
+ p95: 1200
+ ephemeral_storage: 896
+ heap: 6144
+ memory: 7168
+ overhead: 1024
+ executor:
+ estimation:
+ cpu:
+ max: 2000
+ p75: 1200
+ p95: 1500
+ ephemeral_storage: 512
+ heap: 3072
+ memory: 4096
+ overhead: 1024
+ id: dedupeactivecontexts:adp_dedupeactivecontexts_org2
+ type: recommendation
+ schema:
+ $ref: '#/components/schemas/RecommendationDocument'
+ description: OK
+ '400':
+ $ref: '#/components/responses/BadRequestResponse'
+ '403':
+ $ref: '#/components/responses/NotAuthorizedResponse'
+ '429':
+ $ref: '#/components/responses/TooManyRequestsResponse'
+ summary: Get SPA Recommendations
+ tags:
+ - Spa
+ x-unstable: '**Note**: This endpoint is in public beta and may change in the
+ future. It is not yet recommended for production use.'
/api/v2/spans/analytics/aggregate:
post:
description: 'The API endpoint to aggregate spans into buckets and compute metrics
@@ -69127,6 +69294,9 @@ tags:
externalDocs:
url: https://docs.datadoghq.com/service_catalog/service_definitions#metadata-schema-v30-beta
name: Software Catalog
+- description: SPA (Spark Pod Autosizing) API. Provides resource recommendations and
+ cost insights to help optimize Spark job configurations.
+ name: Spa
- description: Search and aggregate your spans from your Datadog platform over HTTP.
name: Spans
- description: Manage configuration of [span-based metrics](https://app.datadoghq.com/apm/traces/generate-metrics)
diff --git a/examples/v2/spa/GetSPARecommendations.java b/examples/v2/spa/GetSPARecommendations.java
new file mode 100644
index 00000000000..6f4859fb5e1
--- /dev/null
+++ b/examples/v2/spa/GetSPARecommendations.java
@@ -0,0 +1,25 @@
+// Get SPA Recommendations returns "OK" response
+
+import com.datadog.api.client.ApiClient;
+import com.datadog.api.client.ApiException;
+import com.datadog.api.client.v2.api.SpaApi;
+import com.datadog.api.client.v2.model.RecommendationDocument;
+
+public class Example {
+ public static void main(String[] args) {
+ ApiClient defaultClient = ApiClient.getDefaultApiClient();
+ defaultClient.setUnstableOperationEnabled("v2.getSPARecommendations", true);
+ SpaApi apiInstance = new SpaApi(defaultClient);
+
+ try {
+ RecommendationDocument result = apiInstance.getSPARecommendations("shard", "service");
+ System.out.println(result);
+ } catch (ApiException e) {
+ System.err.println("Exception when calling SpaApi#getSPARecommendations");
+ 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/ApiClient.java b/src/main/java/com/datadog/api/client/ApiClient.java
index 48a2dd4ee7b..3fe7a9532b3 100644
--- a/src/main/java/com/datadog/api/client/ApiClient.java
+++ b/src/main/java/com/datadog/api/client/ApiClient.java
@@ -772,6 +772,7 @@ public class ApiClient {
put("v2.createSLOReportJob", false);
put("v2.getSLOReport", false);
put("v2.getSLOReportJobStatus", false);
+ put("v2.getSPARecommendations", false);
put("v2.addMemberTeam", false);
put("v2.listMemberTeams", false);
put("v2.removeMemberTeam", false);
diff --git a/src/main/java/com/datadog/api/client/v2/api/SpaApi.java b/src/main/java/com/datadog/api/client/v2/api/SpaApi.java
new file mode 100644
index 00000000000..e2a098df9a3
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/api/SpaApi.java
@@ -0,0 +1,226 @@
+package com.datadog.api.client.v2.api;
+
+import com.datadog.api.client.ApiClient;
+import com.datadog.api.client.ApiException;
+import com.datadog.api.client.ApiResponse;
+import com.datadog.api.client.Pair;
+import com.datadog.api.client.v2.model.RecommendationDocument;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.core.GenericType;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class SpaApi {
+ private ApiClient apiClient;
+
+ public SpaApi() {
+ this(ApiClient.getDefaultApiClient());
+ }
+
+ public SpaApi(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ * Get the API client.
+ *
+ * @return API client
+ */
+ public ApiClient getApiClient() {
+ return apiClient;
+ }
+
+ /**
+ * Set the API client.
+ *
+ * @param apiClient an instance of API client
+ */
+ public void setApiClient(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ * Get SPA Recommendations.
+ *
+ *
See {@link #getSPARecommendationsWithHttpInfo}.
+ *
+ * @param shard The shard tag for a spark job, which differentiates jobs within the same service
+ * that have different resource needs (required)
+ * @param service The service name for a spark job (required)
+ * @return RecommendationDocument
+ * @throws ApiException if fails to make API call
+ */
+ public RecommendationDocument getSPARecommendations(String shard, String service)
+ throws ApiException {
+ return getSPARecommendationsWithHttpInfo(shard, service).getData();
+ }
+
+ /**
+ * Get SPA Recommendations.
+ *
+ *
See {@link #getSPARecommendationsWithHttpInfoAsync}.
+ *
+ * @param shard The shard tag for a spark job, which differentiates jobs within the same service
+ * that have different resource needs (required)
+ * @param service The service name for a spark job (required)
+ * @return CompletableFuture<RecommendationDocument>
+ */
+ public CompletableFuture getSPARecommendationsAsync(
+ String shard, String service) {
+ return getSPARecommendationsWithHttpInfoAsync(shard, service)
+ .thenApply(
+ response -> {
+ return response.getData();
+ });
+ }
+
+ /**
+ * Retrieve resource recommendations for a Spark job. The caller (Spark Gateway or DJM UI)
+ * provides a service name and shard identifier, and SPA returns structured recommendations for
+ * driver and executor resources.
+ *
+ * @param shard The shard tag for a spark job, which differentiates jobs within the same service
+ * that have different resource needs (required)
+ * @param service The service name for a spark job (required)
+ * @return ApiResponse<RecommendationDocument>
+ * @throws ApiException if fails to make API call
+ * @http.response.details
+ *
+ * Response details
+ * | Status Code | Description | Response Headers |
+ * | 200 | OK | - |
+ * | 400 | Bad Request | - |
+ * | 403 | Not Authorized | - |
+ * | 429 | Too many requests | - |
+ *
+ */
+ public ApiResponse getSPARecommendationsWithHttpInfo(
+ String shard, String service) throws ApiException {
+ // Check if unstable operation is enabled
+ String operationId = "getSPARecommendations";
+ if (apiClient.isUnstableOperationEnabled("v2." + operationId)) {
+ apiClient.getLogger().warning(String.format("Using unstable operation '%s'", operationId));
+ } else {
+ throw new ApiException(0, String.format("Unstable operation '%s' is disabled", operationId));
+ }
+ Object localVarPostBody = null;
+
+ // verify the required parameter 'shard' is set
+ if (shard == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'shard' when calling getSPARecommendations");
+ }
+
+ // verify the required parameter 'service' is set
+ if (service == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'service' when calling getSPARecommendations");
+ }
+ // create path and map variables
+ String localVarPath =
+ "/api/v2/spa/recommendations/{service}/{shard}"
+ .replaceAll("\\{" + "shard" + "\\}", apiClient.escapeString(shard.toString()))
+ .replaceAll("\\{" + "service" + "\\}", apiClient.escapeString(service.toString()));
+
+ Map localVarHeaderParams = new HashMap();
+
+ Invocation.Builder builder =
+ apiClient.createBuilder(
+ "v2.SpaApi.getSPARecommendations",
+ localVarPath,
+ new ArrayList(),
+ localVarHeaderParams,
+ new HashMap(),
+ new String[] {"application/json"},
+ new String[] {"apiKeyAuth", "appKeyAuth"});
+ return apiClient.invokeAPI(
+ "GET",
+ builder,
+ localVarHeaderParams,
+ new String[] {},
+ localVarPostBody,
+ new HashMap(),
+ false,
+ new GenericType() {});
+ }
+
+ /**
+ * Get SPA Recommendations.
+ *
+ * See {@link #getSPARecommendationsWithHttpInfo}.
+ *
+ * @param shard The shard tag for a spark job, which differentiates jobs within the same service
+ * that have different resource needs (required)
+ * @param service The service name for a spark job (required)
+ * @return CompletableFuture<ApiResponse<RecommendationDocument>>
+ */
+ public CompletableFuture>
+ getSPARecommendationsWithHttpInfoAsync(String shard, String service) {
+ // Check if unstable operation is enabled
+ String operationId = "getSPARecommendations";
+ if (apiClient.isUnstableOperationEnabled("v2." + operationId)) {
+ apiClient.getLogger().warning(String.format("Using unstable operation '%s'", operationId));
+ } else {
+ CompletableFuture> result = new CompletableFuture<>();
+ result.completeExceptionally(
+ new ApiException(0, String.format("Unstable operation '%s' is disabled", operationId)));
+ return result;
+ }
+ Object localVarPostBody = null;
+
+ // verify the required parameter 'shard' is set
+ if (shard == null) {
+ CompletableFuture> result = new CompletableFuture<>();
+ result.completeExceptionally(
+ new ApiException(
+ 400, "Missing the required parameter 'shard' when calling getSPARecommendations"));
+ return result;
+ }
+
+ // verify the required parameter 'service' is set
+ if (service == null) {
+ CompletableFuture> result = new CompletableFuture<>();
+ result.completeExceptionally(
+ new ApiException(
+ 400, "Missing the required parameter 'service' when calling getSPARecommendations"));
+ return result;
+ }
+ // create path and map variables
+ String localVarPath =
+ "/api/v2/spa/recommendations/{service}/{shard}"
+ .replaceAll("\\{" + "shard" + "\\}", apiClient.escapeString(shard.toString()))
+ .replaceAll("\\{" + "service" + "\\}", apiClient.escapeString(service.toString()));
+
+ Map localVarHeaderParams = new HashMap();
+
+ Invocation.Builder builder;
+ try {
+ builder =
+ apiClient.createBuilder(
+ "v2.SpaApi.getSPARecommendations",
+ localVarPath,
+ new ArrayList(),
+ localVarHeaderParams,
+ new HashMap(),
+ new String[] {"application/json"},
+ new String[] {"apiKeyAuth", "appKeyAuth"});
+ } catch (ApiException ex) {
+ CompletableFuture> result = new CompletableFuture<>();
+ result.completeExceptionally(ex);
+ return result;
+ }
+ return apiClient.invokeAPIAsync(
+ "GET",
+ builder,
+ localVarHeaderParams,
+ new String[] {},
+ localVarPostBody,
+ new HashMap(),
+ false,
+ new GenericType() {});
+ }
+}
diff --git a/src/main/java/com/datadog/api/client/v2/model/ComponentRecommendation.java b/src/main/java/com/datadog/api/client/v2/model/ComponentRecommendation.java
new file mode 100644
index 00000000000..bdc7c9a53fd
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/ComponentRecommendation.java
@@ -0,0 +1,149 @@
+/*
+ * 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.v2.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;
+
+/**
+ * Resource recommendation for a single Spark component (driver or executor). Contains estimation
+ * data used to patch Spark job specs.
+ */
+@JsonPropertyOrder({ComponentRecommendation.JSON_PROPERTY_ESTIMATION})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class ComponentRecommendation {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_ESTIMATION = "estimation";
+ private Estimation estimation;
+
+ public ComponentRecommendation() {}
+
+ @JsonCreator
+ public ComponentRecommendation(
+ @JsonProperty(required = true, value = JSON_PROPERTY_ESTIMATION) Estimation estimation) {
+ this.estimation = estimation;
+ this.unparsed |= estimation.unparsed;
+ }
+
+ public ComponentRecommendation estimation(Estimation estimation) {
+ this.estimation = estimation;
+ this.unparsed |= estimation.unparsed;
+ return this;
+ }
+
+ /**
+ * Recommended resource values for a Spark driver or executor, derived from recent real usage
+ * metrics. Used by SPA to propose more efficient pod sizing.
+ *
+ * @return estimation
+ */
+ @JsonProperty(JSON_PROPERTY_ESTIMATION)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public Estimation getEstimation() {
+ return estimation;
+ }
+
+ public void setEstimation(Estimation estimation) {
+ this.estimation = estimation;
+ }
+
+ /**
+ * 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 ComponentRecommendation
+ */
+ @JsonAnySetter
+ public ComponentRecommendation 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 ComponentRecommendation object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ComponentRecommendation componentRecommendation = (ComponentRecommendation) o;
+ return Objects.equals(this.estimation, componentRecommendation.estimation)
+ && Objects.equals(this.additionalProperties, componentRecommendation.additionalProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(estimation, additionalProperties);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class ComponentRecommendation {\n");
+ sb.append(" estimation: ").append(toIndentedString(estimation)).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/v2/model/Cpu.java b/src/main/java/com/datadog/api/client/v2/model/Cpu.java
new file mode 100644
index 00000000000..7bd2130ebf2
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/Cpu.java
@@ -0,0 +1,193 @@
+/*
+ * 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.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+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;
+
+/**
+ * CPU usage statistics derived from historical Spark job metrics. Provides multiple estimates so
+ * users can choose between conservative and cost-saving risk profiles.
+ */
+@JsonPropertyOrder({Cpu.JSON_PROPERTY_MAX, Cpu.JSON_PROPERTY_P75, Cpu.JSON_PROPERTY_P95})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class Cpu {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_MAX = "max";
+ private Long max;
+
+ public static final String JSON_PROPERTY_P75 = "p75";
+ private Long p75;
+
+ public static final String JSON_PROPERTY_P95 = "p95";
+ private Long p95;
+
+ public Cpu max(Long max) {
+ this.max = max;
+ return this;
+ }
+
+ /**
+ * Maximum CPU usage observed for the job, expressed in millicores. This represents the upper
+ * bound of usage.
+ *
+ * @return max
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_MAX)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Long getMax() {
+ return max;
+ }
+
+ public void setMax(Long max) {
+ this.max = max;
+ }
+
+ public Cpu p75(Long p75) {
+ this.p75 = p75;
+ return this;
+ }
+
+ /**
+ * 75th percentile of CPU usage (millicores). Represents a cost-saving configuration while
+ * covering most workloads.
+ *
+ * @return p75
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_P75)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Long getP75() {
+ return p75;
+ }
+
+ public void setP75(Long p75) {
+ this.p75 = p75;
+ }
+
+ public Cpu p95(Long p95) {
+ this.p95 = p95;
+ return this;
+ }
+
+ /**
+ * 95th percentile of CPU usage (millicores). Balances performance and cost, providing a safer
+ * margin than p75.
+ *
+ * @return p95
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_P95)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Long getP95() {
+ return p95;
+ }
+
+ public void setP95(Long p95) {
+ this.p95 = p95;
+ }
+
+ /**
+ * 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 Cpu
+ */
+ @JsonAnySetter
+ public Cpu 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 Cpu object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Cpu cpu = (Cpu) o;
+ return Objects.equals(this.max, cpu.max)
+ && Objects.equals(this.p75, cpu.p75)
+ && Objects.equals(this.p95, cpu.p95)
+ && Objects.equals(this.additionalProperties, cpu.additionalProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(max, p75, p95, additionalProperties);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class Cpu {\n");
+ sb.append(" max: ").append(toIndentedString(max)).append("\n");
+ sb.append(" p75: ").append(toIndentedString(p75)).append("\n");
+ sb.append(" p95: ").append(toIndentedString(p95)).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/v2/model/Estimation.java b/src/main/java/com/datadog/api/client/v2/model/Estimation.java
new file mode 100644
index 00000000000..04d82688e20
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/Estimation.java
@@ -0,0 +1,250 @@
+/*
+ * 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.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+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;
+
+/**
+ * Recommended resource values for a Spark driver or executor, derived from recent real usage
+ * metrics. Used by SPA to propose more efficient pod sizing.
+ */
+@JsonPropertyOrder({
+ Estimation.JSON_PROPERTY_CPU,
+ Estimation.JSON_PROPERTY_EPHEMERAL_STORAGE,
+ Estimation.JSON_PROPERTY_HEAP,
+ Estimation.JSON_PROPERTY_MEMORY,
+ Estimation.JSON_PROPERTY_OVERHEAD
+})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class Estimation {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_CPU = "cpu";
+ private Cpu cpu;
+
+ public static final String JSON_PROPERTY_EPHEMERAL_STORAGE = "ephemeral_storage";
+ private Long ephemeralStorage;
+
+ public static final String JSON_PROPERTY_HEAP = "heap";
+ private Long heap;
+
+ public static final String JSON_PROPERTY_MEMORY = "memory";
+ private Long memory;
+
+ public static final String JSON_PROPERTY_OVERHEAD = "overhead";
+ private Long overhead;
+
+ public Estimation cpu(Cpu cpu) {
+ this.cpu = cpu;
+ this.unparsed |= cpu.unparsed;
+ return this;
+ }
+
+ /**
+ * CPU usage statistics derived from historical Spark job metrics. Provides multiple estimates so
+ * users can choose between conservative and cost-saving risk profiles.
+ *
+ * @return cpu
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_CPU)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Cpu getCpu() {
+ return cpu;
+ }
+
+ public void setCpu(Cpu cpu) {
+ this.cpu = cpu;
+ }
+
+ public Estimation ephemeralStorage(Long ephemeralStorage) {
+ this.ephemeralStorage = ephemeralStorage;
+ return this;
+ }
+
+ /**
+ * Recommended ephemeral storage allocation (in MiB). Derived from job temporary storage patterns.
+ *
+ * @return ephemeralStorage
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_EPHEMERAL_STORAGE)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Long getEphemeralStorage() {
+ return ephemeralStorage;
+ }
+
+ public void setEphemeralStorage(Long ephemeralStorage) {
+ this.ephemeralStorage = ephemeralStorage;
+ }
+
+ public Estimation heap(Long heap) {
+ this.heap = heap;
+ return this;
+ }
+
+ /**
+ * Recommended JVM heap size (in MiB).
+ *
+ * @return heap
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_HEAP)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Long getHeap() {
+ return heap;
+ }
+
+ public void setHeap(Long heap) {
+ this.heap = heap;
+ }
+
+ public Estimation memory(Long memory) {
+ this.memory = memory;
+ return this;
+ }
+
+ /**
+ * Recommended total memory allocation (in MiB). Includes both heap and overhead.
+ *
+ * @return memory
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_MEMORY)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Long getMemory() {
+ return memory;
+ }
+
+ public void setMemory(Long memory) {
+ this.memory = memory;
+ }
+
+ public Estimation overhead(Long overhead) {
+ this.overhead = overhead;
+ return this;
+ }
+
+ /**
+ * Recommended JVM overhead (in MiB). Computed as total memory - heap.
+ *
+ * @return overhead
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_OVERHEAD)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public Long getOverhead() {
+ return overhead;
+ }
+
+ public void setOverhead(Long overhead) {
+ this.overhead = overhead;
+ }
+
+ /**
+ * 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 Estimation
+ */
+ @JsonAnySetter
+ public Estimation 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 Estimation object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Estimation estimation = (Estimation) o;
+ return Objects.equals(this.cpu, estimation.cpu)
+ && Objects.equals(this.ephemeralStorage, estimation.ephemeralStorage)
+ && Objects.equals(this.heap, estimation.heap)
+ && Objects.equals(this.memory, estimation.memory)
+ && Objects.equals(this.overhead, estimation.overhead)
+ && Objects.equals(this.additionalProperties, estimation.additionalProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(cpu, ephemeralStorage, heap, memory, overhead, additionalProperties);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class Estimation {\n");
+ sb.append(" cpu: ").append(toIndentedString(cpu)).append("\n");
+ sb.append(" ephemeralStorage: ").append(toIndentedString(ephemeralStorage)).append("\n");
+ sb.append(" heap: ").append(toIndentedString(heap)).append("\n");
+ sb.append(" memory: ").append(toIndentedString(memory)).append("\n");
+ sb.append(" overhead: ").append(toIndentedString(overhead)).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/v2/model/RecommendationAttributes.java b/src/main/java/com/datadog/api/client/v2/model/RecommendationAttributes.java
new file mode 100644
index 00000000000..babf04d55e7
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/RecommendationAttributes.java
@@ -0,0 +1,183 @@
+/*
+ * 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.v2.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;
+
+/**
+ * Attributes of the SPA Recommendation resource. Contains recommendations for both driver and
+ * executor components.
+ */
+@JsonPropertyOrder({
+ RecommendationAttributes.JSON_PROPERTY_DRIVER,
+ RecommendationAttributes.JSON_PROPERTY_EXECUTOR
+})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class RecommendationAttributes {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_DRIVER = "driver";
+ private ComponentRecommendation driver;
+
+ public static final String JSON_PROPERTY_EXECUTOR = "executor";
+ private ComponentRecommendation executor;
+
+ public RecommendationAttributes() {}
+
+ @JsonCreator
+ public RecommendationAttributes(
+ @JsonProperty(required = true, value = JSON_PROPERTY_DRIVER) ComponentRecommendation driver,
+ @JsonProperty(required = true, value = JSON_PROPERTY_EXECUTOR)
+ ComponentRecommendation executor) {
+ this.driver = driver;
+ this.unparsed |= driver.unparsed;
+ this.executor = executor;
+ this.unparsed |= executor.unparsed;
+ }
+
+ public RecommendationAttributes driver(ComponentRecommendation driver) {
+ this.driver = driver;
+ this.unparsed |= driver.unparsed;
+ return this;
+ }
+
+ /**
+ * Resource recommendation for a single Spark component (driver or executor). Contains estimation
+ * data used to patch Spark job specs.
+ *
+ * @return driver
+ */
+ @JsonProperty(JSON_PROPERTY_DRIVER)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public ComponentRecommendation getDriver() {
+ return driver;
+ }
+
+ public void setDriver(ComponentRecommendation driver) {
+ this.driver = driver;
+ }
+
+ public RecommendationAttributes executor(ComponentRecommendation executor) {
+ this.executor = executor;
+ this.unparsed |= executor.unparsed;
+ return this;
+ }
+
+ /**
+ * Resource recommendation for a single Spark component (driver or executor). Contains estimation
+ * data used to patch Spark job specs.
+ *
+ * @return executor
+ */
+ @JsonProperty(JSON_PROPERTY_EXECUTOR)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public ComponentRecommendation getExecutor() {
+ return executor;
+ }
+
+ public void setExecutor(ComponentRecommendation executor) {
+ this.executor = executor;
+ }
+
+ /**
+ * 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 RecommendationAttributes
+ */
+ @JsonAnySetter
+ public RecommendationAttributes 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 RecommendationAttributes object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RecommendationAttributes recommendationAttributes = (RecommendationAttributes) o;
+ return Objects.equals(this.driver, recommendationAttributes.driver)
+ && Objects.equals(this.executor, recommendationAttributes.executor)
+ && Objects.equals(this.additionalProperties, recommendationAttributes.additionalProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(driver, executor, additionalProperties);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class RecommendationAttributes {\n");
+ sb.append(" driver: ").append(toIndentedString(driver)).append("\n");
+ sb.append(" executor: ").append(toIndentedString(executor)).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/v2/model/RecommendationData.java b/src/main/java/com/datadog/api/client/v2/model/RecommendationData.java
new file mode 100644
index 00000000000..b972fcfecdb
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/RecommendationData.java
@@ -0,0 +1,213 @@
+/*
+ * 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.v2.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;
+
+/**
+ * JSON:API resource object for SPA Recommendation. Includes type, optional ID, and resource
+ * attributes with structured recommendations.
+ */
+@JsonPropertyOrder({
+ RecommendationData.JSON_PROPERTY_ATTRIBUTES,
+ RecommendationData.JSON_PROPERTY_ID,
+ RecommendationData.JSON_PROPERTY_TYPE
+})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class RecommendationData {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_ATTRIBUTES = "attributes";
+ private RecommendationAttributes attributes;
+
+ public static final String JSON_PROPERTY_ID = "id";
+ private String id;
+
+ public static final String JSON_PROPERTY_TYPE = "type";
+ private RecommendationType type = RecommendationType.RECOMMENDATION;
+
+ public RecommendationData() {}
+
+ @JsonCreator
+ public RecommendationData(
+ @JsonProperty(required = true, value = JSON_PROPERTY_ATTRIBUTES)
+ RecommendationAttributes attributes,
+ @JsonProperty(required = true, value = JSON_PROPERTY_TYPE) RecommendationType type) {
+ this.attributes = attributes;
+ this.unparsed |= attributes.unparsed;
+ this.type = type;
+ this.unparsed |= !type.isValid();
+ }
+
+ public RecommendationData attributes(RecommendationAttributes attributes) {
+ this.attributes = attributes;
+ this.unparsed |= attributes.unparsed;
+ return this;
+ }
+
+ /**
+ * Attributes of the SPA Recommendation resource. Contains recommendations for both driver and
+ * executor components.
+ *
+ * @return attributes
+ */
+ @JsonProperty(JSON_PROPERTY_ATTRIBUTES)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public RecommendationAttributes getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(RecommendationAttributes attributes) {
+ this.attributes = attributes;
+ }
+
+ public RecommendationData id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * Resource identifier for the recommendation. Optional in responses.
+ *
+ * @return id
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_ID)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public RecommendationData type(RecommendationType type) {
+ this.type = type;
+ this.unparsed |= !type.isValid();
+ return this;
+ }
+
+ /**
+ * JSON:API resource type for Spark Pod Autosizing recommendations. Identifies the Recommendation
+ * resource returned by SPA.
+ *
+ * @return type
+ */
+ @JsonProperty(JSON_PROPERTY_TYPE)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public RecommendationType getType() {
+ return type;
+ }
+
+ public void setType(RecommendationType type) {
+ if (!type.isValid()) {
+ this.unparsed = true;
+ }
+ this.type = type;
+ }
+
+ /**
+ * 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 RecommendationData
+ */
+ @JsonAnySetter
+ public RecommendationData 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 RecommendationData object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RecommendationData recommendationData = (RecommendationData) o;
+ return Objects.equals(this.attributes, recommendationData.attributes)
+ && Objects.equals(this.id, recommendationData.id)
+ && Objects.equals(this.type, recommendationData.type)
+ && Objects.equals(this.additionalProperties, recommendationData.additionalProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(attributes, id, type, additionalProperties);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class RecommendationData {\n");
+ sb.append(" attributes: ").append(toIndentedString(attributes)).append("\n");
+ sb.append(" id: ").append(toIndentedString(id)).append("\n");
+ sb.append(" type: ").append(toIndentedString(type)).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/v2/model/RecommendationDocument.java b/src/main/java/com/datadog/api/client/v2/model/RecommendationDocument.java
new file mode 100644
index 00000000000..3037da963d7
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/RecommendationDocument.java
@@ -0,0 +1,149 @@
+/*
+ * 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.v2.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;
+
+/**
+ * JSON:API document containing a single Recommendation resource. Returned by SPA when the Spark
+ * Gateway requests recommendations.
+ */
+@JsonPropertyOrder({RecommendationDocument.JSON_PROPERTY_DATA})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class RecommendationDocument {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_DATA = "data";
+ private RecommendationData data;
+
+ public RecommendationDocument() {}
+
+ @JsonCreator
+ public RecommendationDocument(
+ @JsonProperty(required = true, value = JSON_PROPERTY_DATA) RecommendationData data) {
+ this.data = data;
+ this.unparsed |= data.unparsed;
+ }
+
+ public RecommendationDocument data(RecommendationData data) {
+ this.data = data;
+ this.unparsed |= data.unparsed;
+ return this;
+ }
+
+ /**
+ * JSON:API resource object for SPA Recommendation. Includes type, optional ID, and resource
+ * attributes with structured recommendations.
+ *
+ * @return data
+ */
+ @JsonProperty(JSON_PROPERTY_DATA)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public RecommendationData getData() {
+ return data;
+ }
+
+ public void setData(RecommendationData data) {
+ this.data = data;
+ }
+
+ /**
+ * 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 RecommendationDocument
+ */
+ @JsonAnySetter
+ public RecommendationDocument 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 RecommendationDocument object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RecommendationDocument recommendationDocument = (RecommendationDocument) o;
+ return Objects.equals(this.data, recommendationDocument.data)
+ && Objects.equals(this.additionalProperties, recommendationDocument.additionalProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(data, additionalProperties);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class RecommendationDocument {\n");
+ sb.append(" data: ").append(toIndentedString(data)).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/v2/model/RecommendationType.java b/src/main/java/com/datadog/api/client/v2/model/RecommendationType.java
new file mode 100644
index 00000000000..1cd2370e9bf
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/RecommendationType.java
@@ -0,0 +1,57 @@
+/*
+ * 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.v2.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;
+
+/**
+ * JSON:API resource type for Spark Pod Autosizing recommendations. Identifies the Recommendation
+ * resource returned by SPA.
+ */
+@JsonSerialize(using = RecommendationType.RecommendationTypeSerializer.class)
+public class RecommendationType extends ModelEnum {
+
+ private static final Set allowedValues =
+ new HashSet(Arrays.asList("recommendation"));
+
+ public static final RecommendationType RECOMMENDATION = new RecommendationType("recommendation");
+
+ RecommendationType(String value) {
+ super(value, allowedValues);
+ }
+
+ public static class RecommendationTypeSerializer extends StdSerializer {
+ public RecommendationTypeSerializer(Class t) {
+ super(t);
+ }
+
+ public RecommendationTypeSerializer() {
+ this(null);
+ }
+
+ @Override
+ public void serialize(RecommendationType value, JsonGenerator jgen, SerializerProvider provider)
+ throws IOException, JsonProcessingException {
+ jgen.writeObject(value.value);
+ }
+ }
+
+ @JsonCreator
+ public static RecommendationType fromValue(String value) {
+ return new RecommendationType(value);
+ }
+}
diff --git a/src/test/resources/com/datadog/api/client/v2/api/spa.feature b/src/test/resources/com/datadog/api/client/v2/api/spa.feature
new file mode 100644
index 00000000000..327bbf16ac0
--- /dev/null
+++ b/src/test/resources/com/datadog/api/client/v2/api/spa.feature
@@ -0,0 +1,54 @@
+@endpoint(spa) @endpoint(spa-v2)
+Feature: Spa
+ SPA (Spark Pod Autosizing) API. Provides resource recommendations and cost
+ insights to help optimize Spark job configurations.
+
+ Background:
+ Given a valid "apiKeyAuth" key in the system
+ And a valid "appKeyAuth" key in the system
+ And an instance of "Spa" API
+ And operation "GetSPARecommendations" enabled
+ And new "GetSPARecommendations" request
+
+ @generated @skip @team:DataDog/data-and-analytics-processing
+ Scenario: Get SPA Recommendations returns "Bad Request" response
+ Given request contains "shard" parameter from "REPLACE.ME"
+ And request contains "service" parameter from "REPLACE.ME"
+ When the request is sent
+ Then the response status is 400 Bad Request
+
+ @generated @skip @team:DataDog/data-and-analytics-processing
+ Scenario: Get SPA Recommendations returns "OK" response
+ Given request contains "shard" parameter from "REPLACE.ME"
+ And request contains "service" parameter from "REPLACE.ME"
+ When the request is sent
+ Then the response status is 200 OK
+
+ @skip @team:DataDog/data-and-analytics-processing
+ Scenario: GetSPARecommendations returns a JSON:API Recommendation with driver and executor estimations
+ Given request contains "service" parameter with value "dedupeactivecontexts"
+ And request contains "shard" parameter with value "adp_dedupeactivecontexts_org2"
+ When the request is sent
+ Then the response status is 404 Not Found
+ And the response "data.type" is equal to "recommendation"
+ And the response "data" has field "attributes"
+ And the response "data.attributes" has field "driver"
+ And the response "data.attributes" has field "executor"
+ And the response "data.attributes.driver" has field "estimation"
+ And the response "data.attributes.driver.estimation" has field "cpu"
+ And the response "data.attributes.driver.estimation" has field "memory"
+ And the response "data.attributes.driver.estimation" has field "ephemeral_storage"
+ And the response "data.attributes.driver.estimation" has field "heap"
+ And the response "data.attributes.driver.estimation" has field "overhead"
+ And the response "data.attributes.driver.estimation.cpu" has field "max"
+ And the response "data.attributes.driver.estimation.cpu" has field "p95"
+ And the response "data.attributes.driver.estimation.cpu" has field "p75"
+ And the response "data.attributes.executor" has field "estimation"
+ And the response "data.attributes.executor.estimation" has field "cpu"
+ And the response "data.attributes.executor.estimation" has field "memory"
+ And the response "data.attributes.executor.estimation" has field "ephemeral_storage"
+ And the response "data.attributes.executor.estimation" has field "heap"
+ And the response "data.attributes.executor.estimation" has field "overhead"
+ And the response "data.attributes.executor.estimation.cpu" has field "max"
+ And the response "data.attributes.executor.estimation.cpu" has field "p95"
+ And the response "data.attributes.executor.estimation.cpu" has field "p75"
diff --git a/src/test/resources/com/datadog/api/client/v2/api/undo.json b/src/test/resources/com/datadog/api/client/v2/api/undo.json
index 6f5c5499f1c..9878d7a4678 100644
--- a/src/test/resources/com/datadog/api/client/v2/api/undo.json
+++ b/src/test/resources/com/datadog/api/client/v2/api/undo.json
@@ -3362,6 +3362,12 @@
"type": "safe"
}
},
+ "GetSPARecommendations": {
+ "tag": "Spa",
+ "undo": {
+ "type": "safe"
+ }
+ },
"AggregateSpans": {
"tag": "Spans",
"undo": {