From 1042dc7050326675aef26d4668d0b0c578b0d4bf Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Fri, 2 Oct 2026 15:38:30 +0000 Subject: [PATCH] Regenerate client from commit c7c1fad of spec repo --- .generator/schemas/v2/openapi.yaml | 105 +++++++++++ features/v2/spa.feature | 27 +++ features/v2/undo.json | 6 + .../src/support/scenarios_model_mapping.ts | 11 ++ services/spa/README.md | 4 +- services/spa/src/v2/SpaApi.ts | 168 ++++++++++++++++++ services/spa/src/v2/index.ts | 5 + .../RecommendationV2RequestAttributes.ts | 47 +++++ .../v2/models/RecommendationV2RequestBody.ts | 48 +++++ .../v2/models/RecommendationV2RequestData.ts | 58 ++++++ .../v2/models/RecommendationV2RequestType.ts | 9 + services/spa/src/v2/models/TypingInfo.ts | 7 + 12 files changed, 493 insertions(+), 2 deletions(-) create mode 100644 services/spa/src/v2/models/RecommendationV2RequestAttributes.ts create mode 100644 services/spa/src/v2/models/RecommendationV2RequestBody.ts create mode 100644 services/spa/src/v2/models/RecommendationV2RequestData.ts create mode 100644 services/spa/src/v2/models/RecommendationV2RequestType.ts diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 9dd8e972ab6d..62da8be0f948 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -92998,6 +92998,49 @@ components: type: string x-enum-varnames: - RECOMMENDATION + RecommendationV2RequestAttributes: + description: |- + Attributes for requesting SPA recommendations by forwarding a Spark job's raw arguments + instead of a precomputed shard. + properties: + arguments: + description: |- + Raw, unfiltered Spark job arguments as submitted (for example, `--org_id=2`). + SPA determines which arguments are relevant for the given service. + example: + - "" + items: + type: string + type: array + required: [arguments] + type: object + RecommendationV2RequestBody: + description: |- + Request body for retrieving SPA recommendations by forwarding a Spark job's raw arguments + instead of a precomputed shard. + properties: + data: + $ref: "#/components/schemas/RecommendationV2RequestData" + required: [data] + type: object + RecommendationV2RequestData: + description: JSON:API resource object for the SPA v2 recommendation request. + properties: + attributes: + $ref: "#/components/schemas/RecommendationV2RequestAttributes" + type: + $ref: "#/components/schemas/RecommendationV2RequestType" + required: [type, attributes] + type: object + RecommendationV2RequestType: + default: recommendation_v2_request + description: JSON:API resource type for the SPA v2 recommendation request. + enum: + - recommendation_v2_request + example: recommendation_v2_request + type: string + x-enum-varnames: + - RECOMMENDATION_V2_REQUEST RecommendationsFilterRequest: description: JSON:API request body for filtering cost recommendations. example: @@ -218752,6 +218795,68 @@ paths: x-unstable: |- **Note**: This endpoint is in preview and is subject to change. If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/spa/recommendations-v2/{service}: + post: + description: |- + This endpoint is experimental and restricted to Datadog internal use only. + Retrieve resource recommendations for a Spark job. The caller (Spark Gateway) provides + a service name and the job's raw arguments. SPA determines which arguments are relevant + for the service and returns structured recommendations for driver and executor resources. + operationId: GetSPARecommendationsV2 + parameters: + - description: The service name for a Spark job + in: path + name: service + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RecommendationV2RequestBody" + required: true + 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" + "404": + $ref: "#/components/responses/NotFoundResponse" + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - AuthZ: [] + summary: Get SPA recommendations v2 + tags: + - Spa + x-unstable: |- + **Note**: This endpoint is in preview and may change in the future. It is not yet recommended for production use. /api/v2/spa/recommendations/{service}: get: description: This endpoint is currently experimental and restricted to Datadog internal use only. Retrieve resource recommendations for a Spark job. The caller (Spark Gateway or DJM UI) provides a service name and SPA returns structured recommendations for driver and executor resources. The version with a shard should be preferred, where possible, as it gives more accurate results. diff --git a/features/v2/spa.feature b/features/v2/spa.feature index 0e6ac6b3a76b..b3d5d0fec0c2 100644 --- a/features/v2/spa.feature +++ b/features/v2/spa.feature @@ -40,6 +40,33 @@ Feature: Spa When the request is sent Then the response status is 200 OK + @generated @skip @team:DataDog/data-and-analytics-processing + Scenario: Get SPA recommendations v2 returns "Bad Request" response + Given operation "GetSPARecommendationsV2" enabled + And new "GetSPARecommendationsV2" request + And request contains "service" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"arguments": [""]}, "type": "recommendation_v2_request"}} + 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 v2 returns "Not Found" response + Given operation "GetSPARecommendationsV2" enabled + And new "GetSPARecommendationsV2" request + And request contains "service" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"arguments": [""]}, "type": "recommendation_v2_request"}} + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/data-and-analytics-processing + Scenario: Get SPA recommendations v2 returns "OK" response + Given operation "GetSPARecommendationsV2" enabled + And new "GetSPARecommendationsV2" request + And request contains "service" parameter from "REPLACE.ME" + And body with value {"data": {"attributes": {"arguments": [""]}, "type": "recommendation_v2_request"}} + 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 new "GetSPARecommendations" request diff --git a/features/v2/undo.json b/features/v2/undo.json index 8ad9cc9418f1..0f86041e11e6 100644 --- a/features/v2/undo.json +++ b/features/v2/undo.json @@ -9323,6 +9323,12 @@ "type": "unsafe" } }, + "GetSPARecommendationsV2": { + "tag": "Spa", + "undo": { + "type": "safe" + } + }, "GetSPARecommendations": { "tag": "Spa", "undo": { diff --git a/private/bdd_runner/src/support/scenarios_model_mapping.ts b/private/bdd_runner/src/support/scenarios_model_mapping.ts index bf51e4694f8e..1bf369a12ffc 100644 --- a/private/bdd_runner/src/support/scenarios_model_mapping.ts +++ b/private/bdd_runner/src/support/scenarios_model_mapping.ts @@ -17386,6 +17386,17 @@ export const ScenariosModelMappings: { [key: string]: OperationMapping } = { }, operationResponseType: "CreateSnapshotResponse", }, + "SpaApi.V2.GetSPARecommendationsV2": { + service: { + type: "string", + format: "", + }, + body: { + type: "RecommendationV2RequestBody", + format: "", + }, + operationResponseType: "RecommendationDocument", + }, "SpaApi.V2.GetSPARecommendations": { bypassCache: { type: "string", diff --git a/services/spa/README.md b/services/spa/README.md index 1013f3610dac..7ab98213f939 100644 --- a/services/spa/README.md +++ b/services/spa/README.md @@ -28,7 +28,7 @@ const configuration = createConfiguration(); // Enable unstable operations const configurationOpts = { unstableOperations: { - "SpaApi.v2.getSPARecommendations": true + "SpaApi.v2.getSPARecommendationsV2": true } } @@ -36,7 +36,7 @@ const configuration = createConfiguration(configurationOpts); const apiInstance = new SpaApiV2(configuration); const params = {/* parameters */}; -apiInstance.getSPARecommendations(params).then((data) => { +apiInstance.getSPARecommendationsV2(params).then((data) => { console.log("API called successfully. Returned data: " + JSON.stringify(data)); }).catch((error) => { console.error("Error calling API: " + error); diff --git a/services/spa/src/v2/SpaApi.ts b/services/spa/src/v2/SpaApi.ts index 1726093776df..9d832f29613b 100644 --- a/services/spa/src/v2/SpaApi.ts +++ b/services/spa/src/v2/SpaApi.ts @@ -24,6 +24,7 @@ import { import { TypingInfo } from "./models/TypingInfo"; import { APIErrorResponse } from "./models/APIErrorResponse"; import { RecommendationDocument } from "./models/RecommendationDocument"; +import { RecommendationV2RequestBody } from "./models/RecommendationV2RequestBody"; import { version } from "../version"; export class SpaApiRequestFactory extends BaseAPIRequestFactory { @@ -97,6 +98,73 @@ export class SpaApiRequestFactory extends BaseAPIRequestFactory { return requestContext; } + public async getSPARecommendationsV2( + service: string, + body: RecommendationV2RequestBody, + _options?: Configuration, + ): Promise { + const _config = _options || this.configuration; + + if (!_config.unstableOperations["SpaApi.v2.getSPARecommendationsV2"]) { + throw new Error( + "Unstable operation 'getSPARecommendationsV2' is disabled. Enable it by setting `configuration.unstableOperations['SpaApi.v2.getSPARecommendationsV2'] = true`", + ); + } + + // verify required parameter 'service' is not null or undefined + if (service === null || service === undefined) { + throw new RequiredError("service", "getSPARecommendationsV2"); + } + + // verify required parameter 'body' is not null or undefined + if (body === null || body === undefined) { + throw new RequiredError("body", "getSPARecommendationsV2"); + } + + // Path Params + const localVarPath = "/api/v2/spa/recommendations-v2/{service}".replace( + "{service}", + encodeURIComponent(String(service)), + ); + + // Make Request Context + const { server, overrides } = _config.getServerAndOverrides( + "SpaApi.v2.getSPARecommendationsV2", + SpaApi.operationServers, + ); + const requestContext = server.makeRequestContext( + localVarPath, + HttpMethod.POST, + overrides, + ); + requestContext.setHeaderParam("Accept", "application/json"); + requestContext.setHttpConfig(_config.httpConfig); + + // Set User-Agent + if (this.userAgent) { + requestContext.setHeaderParam("User-Agent", this.userAgent); + } + + // Set IaC header + if (_config.isIaC) { + requestContext.setHeaderParam("X-Datadog-Managed-By", "iac"); + } + + // Body Params + const contentType = getPreferredMediaType(["application/json"]); + requestContext.setHeaderParam("Content-Type", contentType); + const serializedBody = stringify( + serialize(body, TypingInfo, "RecommendationV2RequestBody", ""), + contentType, + ); + requestContext.setBody(serializedBody); + + // Apply auth methods + applySecurityAuthentication(_config, requestContext, ["AuthZ"]); + + return requestContext; + } + public async getSPARecommendationsWithShard( shard: string, service: string, @@ -228,6 +296,67 @@ export class SpaApiResponseProcessor { ); } + /** + * Unwraps the actual response sent by the server from the response context and deserializes the response content + * to the expected objects + * + * @params response Response returned by the server for a request to getSPARecommendationsV2 + * @throws ApiException if the response code was not in [200, 299] + */ + public async getSPARecommendationsV2( + response: ResponseContext, + ): Promise { + const contentType = normalizeMediaType(response.headers["content-type"]); + if (response.httpStatusCode === 200) { + const body: RecommendationDocument = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "RecommendationDocument", + ) as RecommendationDocument; + return body; + } + if ( + response.httpStatusCode === 400 || + response.httpStatusCode === 403 || + response.httpStatusCode === 404 || + response.httpStatusCode === 429 + ) { + const bodyText = parse(await response.body.text(), contentType); + let body: APIErrorResponse; + try { + body = deserialize( + bodyText, + TypingInfo, + "APIErrorResponse", + ) as APIErrorResponse; + } catch (error) { + logger.debug(`Got error deserializing error: ${error}`); + throw new ApiException( + response.httpStatusCode, + bodyText, + ); + } + throw new ApiException(response.httpStatusCode, body); + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + const body: RecommendationDocument = deserialize( + parse(await response.body.text(), contentType), + TypingInfo, + "RecommendationDocument", + "", + ) as RecommendationDocument; + return body; + } + + const body = (await response.body.text()) || ""; + throw new ApiException( + response.httpStatusCode, + 'Unknown API Status Code!\nBody: "' + body + '"', + ); + } + /** * Unwraps the actual response sent by the server from the response context and deserializes the response content * to the expected objects @@ -302,6 +431,18 @@ export interface SpaApiGetSPARecommendationsRequest { bypassCache?: string; } +export interface SpaApiGetSPARecommendationsV2Request { + /** + * The service name for a Spark job + * @type string + */ + service: string; + /** + * @type RecommendationV2RequestBody + */ + body: RecommendationV2RequestBody; +} + export interface SpaApiGetSPARecommendationsWithShardRequest { /** * The shard tag for a spark job, which differentiates jobs within the same service that have different resource needs @@ -360,6 +501,33 @@ export class SpaApi { }); } + /** + * This endpoint is experimental and restricted to Datadog internal use only. + * Retrieve resource recommendations for a Spark job. The caller (Spark Gateway) provides + * a service name and the job's raw arguments. SPA determines which arguments are relevant + * for the service and returns structured recommendations for driver and executor resources. + * @param param The request object + */ + public getSPARecommendationsV2( + param: SpaApiGetSPARecommendationsV2Request, + options?: Configuration, + ): Promise { + const requestContextPromise = this.requestFactory.getSPARecommendationsV2( + param.service, + param.body, + options, + ); + return requestContextPromise.then((requestContext) => { + return this.configuration.httpApi + .send(requestContext) + .then((responseContext) => { + return this.responseProcessor.getSPARecommendationsV2( + responseContext, + ); + }); + }); + } + /** * This endpoint is currently experimental and restricted to Datadog internal use only. 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 param The request object diff --git a/services/spa/src/v2/index.ts b/services/spa/src/v2/index.ts index 46c3f89c9e53..aeeeed8a7929 100644 --- a/services/spa/src/v2/index.ts +++ b/services/spa/src/v2/index.ts @@ -1,5 +1,6 @@ export { SpaApiGetSPARecommendationsRequest, + SpaApiGetSPARecommendationsV2Request, SpaApiGetSPARecommendationsWithShardRequest, SpaApi, } from "./SpaApi"; @@ -12,3 +13,7 @@ export { RecommendationAttributes } from "./models/RecommendationAttributes"; export { RecommendationData } from "./models/RecommendationData"; export { RecommendationDocument } from "./models/RecommendationDocument"; export { RecommendationType } from "./models/RecommendationType"; +export { RecommendationV2RequestAttributes } from "./models/RecommendationV2RequestAttributes"; +export { RecommendationV2RequestBody } from "./models/RecommendationV2RequestBody"; +export { RecommendationV2RequestData } from "./models/RecommendationV2RequestData"; +export { RecommendationV2RequestType } from "./models/RecommendationV2RequestType"; diff --git a/services/spa/src/v2/models/RecommendationV2RequestAttributes.ts b/services/spa/src/v2/models/RecommendationV2RequestAttributes.ts new file mode 100644 index 000000000000..517d6218ada4 --- /dev/null +++ b/services/spa/src/v2/models/RecommendationV2RequestAttributes.ts @@ -0,0 +1,47 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +/** + * Attributes for requesting SPA recommendations by forwarding a Spark job's raw arguments + * instead of a precomputed shard. + */ +export class RecommendationV2RequestAttributes { + /** + * Raw, unfiltered Spark job arguments as submitted (for example, `--org_id=2`). + * SPA determines which arguments are relevant for the given service. + */ + "arguments": Array; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + arguments: { + baseName: "arguments", + type: "Array", + required: true, + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return RecommendationV2RequestAttributes.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/spa/src/v2/models/RecommendationV2RequestBody.ts b/services/spa/src/v2/models/RecommendationV2RequestBody.ts new file mode 100644 index 000000000000..496a481b7055 --- /dev/null +++ b/services/spa/src/v2/models/RecommendationV2RequestBody.ts @@ -0,0 +1,48 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { RecommendationV2RequestData } from "./RecommendationV2RequestData"; + +/** + * Request body for retrieving SPA recommendations by forwarding a Spark job's raw arguments + * instead of a precomputed shard. + */ +export class RecommendationV2RequestBody { + /** + * JSON:API resource object for the SPA v2 recommendation request. + */ + "data": RecommendationV2RequestData; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + data: { + baseName: "data", + type: "RecommendationV2RequestData", + required: true, + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return RecommendationV2RequestBody.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/spa/src/v2/models/RecommendationV2RequestData.ts b/services/spa/src/v2/models/RecommendationV2RequestData.ts new file mode 100644 index 000000000000..4079e72f822d --- /dev/null +++ b/services/spa/src/v2/models/RecommendationV2RequestData.ts @@ -0,0 +1,58 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { RecommendationV2RequestAttributes } from "./RecommendationV2RequestAttributes"; +import { RecommendationV2RequestType } from "./RecommendationV2RequestType"; + +/** + * JSON:API resource object for the SPA v2 recommendation request. + */ +export class RecommendationV2RequestData { + /** + * Attributes for requesting SPA recommendations by forwarding a Spark job's raw arguments + * instead of a precomputed shard. + */ + "attributes": RecommendationV2RequestAttributes; + /** + * JSON:API resource type for the SPA v2 recommendation request. + */ + "type": RecommendationV2RequestType; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + attributes: { + baseName: "attributes", + type: "RecommendationV2RequestAttributes", + required: true, + }, + type: { + baseName: "type", + type: "RecommendationV2RequestType", + required: true, + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return RecommendationV2RequestData.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/spa/src/v2/models/RecommendationV2RequestType.ts b/services/spa/src/v2/models/RecommendationV2RequestType.ts new file mode 100644 index 000000000000..19b5cc85496e --- /dev/null +++ b/services/spa/src/v2/models/RecommendationV2RequestType.ts @@ -0,0 +1,9 @@ +import { UnparsedObject } from "@datadog/datadog-api-client"; + +/** + * JSON:API resource type for the SPA v2 recommendation request. + */ +export type RecommendationV2RequestType = + | typeof RECOMMENDATION_V2_REQUEST + | UnparsedObject; +export const RECOMMENDATION_V2_REQUEST = "recommendation_v2_request"; diff --git a/services/spa/src/v2/models/TypingInfo.ts b/services/spa/src/v2/models/TypingInfo.ts index 4dba0caeff5c..b87a25ede42f 100644 --- a/services/spa/src/v2/models/TypingInfo.ts +++ b/services/spa/src/v2/models/TypingInfo.ts @@ -7,10 +7,14 @@ import { Estimation } from "./Estimation"; import { RecommendationAttributes } from "./RecommendationAttributes"; import { RecommendationData } from "./RecommendationData"; import { RecommendationDocument } from "./RecommendationDocument"; +import { RecommendationV2RequestAttributes } from "./RecommendationV2RequestAttributes"; +import { RecommendationV2RequestBody } from "./RecommendationV2RequestBody"; +import { RecommendationV2RequestData } from "./RecommendationV2RequestData"; export const TypingInfo: ModelTypingInfo = { enumsMap: { RecommendationType: ["recommendation"], + RecommendationV2RequestType: ["recommendation_v2_request"], }, oneOfMap: {}, typeMap: { @@ -21,5 +25,8 @@ export const TypingInfo: ModelTypingInfo = { RecommendationAttributes: RecommendationAttributes, RecommendationData: RecommendationData, RecommendationDocument: RecommendationDocument, + RecommendationV2RequestAttributes: RecommendationV2RequestAttributes, + RecommendationV2RequestBody: RecommendationV2RequestBody, + RecommendationV2RequestData: RecommendationV2RequestData, }, };