Skip to content

Commit 9df3a3e

Browse files
tsp, fix response of LRO POST action in ARM (#2801)
1 parent 4dda2b9 commit 9df3a3e

File tree

28 files changed

+694
-158
lines changed

28 files changed

+694
-158
lines changed

typespec-extension/src/code-model-builder.ts

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,7 @@ export class CodeModelBuilder {
828828
const lroMetadata = this.processLroMetadata(codeModelOperation, op);
829829

830830
// responses
831-
const candidateResponseSchema = lroMetadata.pollResultType; // candidate: response body type of pollingOperation
832-
op.responses.map((it) => this.processResponse(codeModelOperation, it, candidateResponseSchema));
831+
op.responses.map((it) => this.processResponse(codeModelOperation, it, lroMetadata.longRunning));
833832

834833
// check for paged
835834
this.processRouteForPaged(codeModelOperation, op.responses);
@@ -871,6 +870,8 @@ export class CodeModelBuilder {
871870
private processLroMetadata(op: CodeModelOperation, httpOperation: HttpOperation): LongRunningMetadata {
872871
const operation = httpOperation.operation;
873872

873+
const trackConvenienceApi: boolean = Boolean(op.convenienceApi);
874+
874875
const lroMetadata = getLroMetadata(this.program, operation);
875876
// needs lroMetadata.statusMonitorStep, as getLroMetadata would return for @pollingOperation operation
876877
if (lroMetadata && lroMetadata.pollingInfo && lroMetadata.statusMonitorStep) {
@@ -930,15 +931,15 @@ export class CodeModelBuilder {
930931
// track usage
931932
if (pollingSchema) {
932933
this.trackSchemaUsage(pollingSchema, { usage: [SchemaContext.Output] });
933-
if (op.convenienceApi) {
934+
if (trackConvenienceApi) {
934935
this.trackSchemaUsage(pollingSchema, {
935936
usage: [op.internalApi ? SchemaContext.Internal : SchemaContext.Public],
936937
});
937938
}
938939
}
939940
if (finalSchema) {
940941
this.trackSchemaUsage(finalSchema, { usage: [SchemaContext.Output] });
941-
if (op.convenienceApi) {
942+
if (trackConvenienceApi) {
942943
this.trackSchemaUsage(finalSchema, {
943944
usage: [op.internalApi ? SchemaContext.Internal : SchemaContext.Public],
944945
});
@@ -1506,11 +1507,7 @@ export class CodeModelBuilder {
15061507
return this.getEffectiveSchemaType(bodyType);
15071508
}
15081509

1509-
private processResponse(
1510-
op: CodeModelOperation,
1511-
resp: HttpOperationResponse,
1512-
candidateResponseSchema: Schema | undefined = undefined,
1513-
) {
1510+
private processResponse(op: CodeModelOperation, resp: HttpOperationResponse, longRunning: boolean) {
15141511
// TODO: what to do if more than 1 response?
15151512
// It happens when the response type is Union, on one status code.
15161513
let response: Response;
@@ -1540,7 +1537,7 @@ export class CodeModelBuilder {
15401537

15411538
let responseBody: HttpOperationBody | undefined = undefined;
15421539
let bodyType: Type | undefined = undefined;
1543-
let trackConvenienceApi = op.convenienceApi ?? false;
1540+
let trackConvenienceApi: boolean = Boolean(op.convenienceApi);
15441541
if (resp.responses && resp.responses.length > 0 && resp.responses[0].body) {
15451542
responseBody = resp.responses[0].body;
15461543
}
@@ -1570,53 +1567,13 @@ export class CodeModelBuilder {
15701567
} else {
15711568
// schema (usually JSON)
15721569
let schema: Schema | undefined = undefined;
1573-
const verb = op.requests?.[0].protocol?.http?.method;
1574-
if (
1575-
// LRO, candidateResponseSchema is Model/ObjectSchema
1576-
candidateResponseSchema &&
1577-
candidateResponseSchema instanceof ObjectSchema &&
1578-
// bodyType is templated Model
1579-
bodyType.kind === "Model" &&
1580-
bodyType.templateMapper &&
1581-
bodyType.templateMapper.args &&
1582-
bodyType.templateMapper.args.length > 0
1583-
) {
1584-
if (verb === "post") {
1585-
// for LRO ResourceAction, the standard does not require a final type, hence it can be the same as intermediate type
1586-
// https://github.com/microsoft/api-guidelines/blob/vNext/azure/ConsiderationsForServiceDesign.md#long-running-action-operations
1587-
1588-
// check if we can use candidateResponseSchema as response schema (instead of the templated Model), for LRO ResourceAction
1589-
if (candidateResponseSchema.properties?.length === bodyType.properties.size) {
1590-
let match = true;
1591-
for (const prop of Array.from(bodyType.properties.values())) {
1592-
const name = this.getName(prop);
1593-
if (!candidateResponseSchema.properties?.find((it) => it.language.default.name === name)) {
1594-
match = false;
1595-
break;
1596-
}
1597-
}
1598-
if (match) {
1599-
schema = candidateResponseSchema;
1600-
const sdkType = getClientType(this.sdkContext, bodyType);
1601-
const modelName = sdkType.kind === "model" ? sdkType.name : undefined;
1602-
this.trace(
1603-
`Replace TypeSpec model '${modelName}' with '${candidateResponseSchema.language.default.name}'`,
1604-
);
1605-
}
1606-
}
1607-
} else if (verb === "delete") {
1608-
// for LRO ResourceDelete, final type will be replaced to "Void" in convenience API, hence do not generate the class
1609-
trackConvenienceApi = false;
1610-
}
1570+
if (longRunning) {
1571+
// LRO uses the LroMetadata for poll/final result, not the response of activation request
1572+
trackConvenienceApi = false;
16111573
}
16121574
if (!schema) {
1613-
if (verb === "post" && op.lroMetadata && op.lroMetadata.pollResultType) {
1614-
// for standard LRO action, return type is the pollResultType
1615-
schema = op.lroMetadata.pollResultType;
1616-
} else {
1617-
const sdkType = getClientType(this.sdkContext, bodyType);
1618-
schema = this.processSchemaFromSdkType(sdkType, op.language.default.name + "Response");
1619-
}
1575+
const sdkType = getClientType(this.sdkContext, bodyType);
1576+
schema = this.processSchemaFromSdkType(sdkType, op.language.default.name + "Response");
16201577
}
16211578
response = new SchemaResponse(schema, {
16221579
protocol: {

typespec-tests/src/main/java/com/_specs_/azure/core/lro/rpc/RpcAsyncClient.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public final class RpcAsyncClient {
5353
* <pre>{@code
5454
* {
5555
* id: String (Required)
56-
* status: String (Required)
56+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
5757
* error (Optional): {
5858
* code: String (Required)
5959
* message: String (Required)
@@ -62,6 +62,9 @@ public final class RpcAsyncClient {
6262
* (recursive schema, see above)
6363
* ]
6464
* }
65+
* result (Optional): {
66+
* data: String (Required)
67+
* }
6568
* }
6669
* }</pre>
6770
*
@@ -71,7 +74,7 @@ public final class RpcAsyncClient {
7174
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
7275
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
7376
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
74-
* @return the {@link PollerFlux} for polling of status details for long running operations.
77+
* @return the {@link PollerFlux} for polling of provides status details for long running operations.
7578
*/
7679
@Generated
7780
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)
@@ -90,7 +93,7 @@ public PollerFlux<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
9093
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
9194
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
9295
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
93-
* @return the {@link PollerFlux} for polling of status details for long running operations.
96+
* @return the {@link PollerFlux} for polling of provides status details for long running operations.
9497
*/
9598
@Generated
9699
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)

typespec-tests/src/main/java/com/_specs_/azure/core/lro/rpc/RpcClient.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public final class RpcClient {
5353
* <pre>{@code
5454
* {
5555
* id: String (Required)
56-
* status: String (Required)
56+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
5757
* error (Optional): {
5858
* code: String (Required)
5959
* message: String (Required)
@@ -62,6 +62,9 @@ public final class RpcClient {
6262
* (recursive schema, see above)
6363
* ]
6464
* }
65+
* result (Optional): {
66+
* data: String (Required)
67+
* }
6568
* }
6669
* }</pre>
6770
*
@@ -71,7 +74,7 @@ public final class RpcClient {
7174
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
7275
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
7376
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
74-
* @return the {@link SyncPoller} for polling of status details for long running operations.
77+
* @return the {@link SyncPoller} for polling of provides status details for long running operations.
7578
*/
7679
@Generated
7780
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)
@@ -90,7 +93,7 @@ public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
9093
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
9194
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
9295
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
93-
* @return the {@link SyncPoller} for polling of status details for long running operations.
96+
* @return the {@link SyncPoller} for polling of provides status details for long running operations.
9497
*/
9598
@Generated
9699
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)

typespec-tests/src/main/java/com/_specs_/azure/core/lro/rpc/implementation/RpcClientImpl.java

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ Response<BinaryData> longRunningRpcSync(@QueryParam("api-version") String apiVer
168168
* <pre>{@code
169169
* {
170170
* id: String (Required)
171-
* status: String (Required)
171+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
172172
* error (Optional): {
173173
* code: String (Required)
174174
* message: String (Required)
@@ -177,6 +177,9 @@ Response<BinaryData> longRunningRpcSync(@QueryParam("api-version") String apiVer
177177
* (recursive schema, see above)
178178
* ]
179179
* }
180+
* result (Optional): {
181+
* data: String (Required)
182+
* }
180183
* }
181184
* }</pre>
182185
*
@@ -186,8 +189,8 @@ Response<BinaryData> longRunningRpcSync(@QueryParam("api-version") String apiVer
186189
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
187190
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
188191
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
189-
* @return status details for long running operations along with {@link Response} on successful completion of
190-
* {@link Mono}.
192+
* @return provides status details for long running operations along with {@link Response} on successful completion
193+
* of {@link Mono}.
191194
*/
192195
@ServiceMethod(returns = ReturnType.SINGLE)
193196
private Mono<Response<BinaryData>> longRunningRpcWithResponseAsync(BinaryData generationOptions,
@@ -212,7 +215,7 @@ private Mono<Response<BinaryData>> longRunningRpcWithResponseAsync(BinaryData ge
212215
* <pre>{@code
213216
* {
214217
* id: String (Required)
215-
* status: String (Required)
218+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
216219
* error (Optional): {
217220
* code: String (Required)
218221
* message: String (Required)
@@ -221,6 +224,9 @@ private Mono<Response<BinaryData>> longRunningRpcWithResponseAsync(BinaryData ge
221224
* (recursive schema, see above)
222225
* ]
223226
* }
227+
* result (Optional): {
228+
* data: String (Required)
229+
* }
224230
* }
225231
* }</pre>
226232
*
@@ -230,7 +236,7 @@ private Mono<Response<BinaryData>> longRunningRpcWithResponseAsync(BinaryData ge
230236
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
231237
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
232238
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
233-
* @return status details for long running operations along with {@link Response}.
239+
* @return provides status details for long running operations along with {@link Response}.
234240
*/
235241
@ServiceMethod(returns = ReturnType.SINGLE)
236242
private Response<BinaryData> longRunningRpcWithResponse(BinaryData generationOptions,
@@ -255,7 +261,7 @@ private Response<BinaryData> longRunningRpcWithResponse(BinaryData generationOpt
255261
* <pre>{@code
256262
* {
257263
* id: String (Required)
258-
* status: String (Required)
264+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
259265
* error (Optional): {
260266
* code: String (Required)
261267
* message: String (Required)
@@ -264,6 +270,9 @@ private Response<BinaryData> longRunningRpcWithResponse(BinaryData generationOpt
264270
* (recursive schema, see above)
265271
* ]
266272
* }
273+
* result (Optional): {
274+
* data: String (Required)
275+
* }
267276
* }
268277
* }</pre>
269278
*
@@ -273,7 +282,7 @@ private Response<BinaryData> longRunningRpcWithResponse(BinaryData generationOpt
273282
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
274283
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
275284
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
276-
* @return the {@link PollerFlux} for polling of status details for long running operations.
285+
* @return the {@link PollerFlux} for polling of provides status details for long running operations.
277286
*/
278287
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)
279288
public PollerFlux<BinaryData, BinaryData> beginLongRunningRpcAsync(BinaryData generationOptions,
@@ -306,7 +315,7 @@ public PollerFlux<BinaryData, BinaryData> beginLongRunningRpcAsync(BinaryData ge
306315
* <pre>{@code
307316
* {
308317
* id: String (Required)
309-
* status: String (Required)
318+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
310319
* error (Optional): {
311320
* code: String (Required)
312321
* message: String (Required)
@@ -315,6 +324,9 @@ public PollerFlux<BinaryData, BinaryData> beginLongRunningRpcAsync(BinaryData ge
315324
* (recursive schema, see above)
316325
* ]
317326
* }
327+
* result (Optional): {
328+
* data: String (Required)
329+
* }
318330
* }
319331
* }</pre>
320332
*
@@ -324,7 +336,7 @@ public PollerFlux<BinaryData, BinaryData> beginLongRunningRpcAsync(BinaryData ge
324336
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
325337
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
326338
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
327-
* @return the {@link SyncPoller} for polling of status details for long running operations.
339+
* @return the {@link SyncPoller} for polling of provides status details for long running operations.
328340
*/
329341
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)
330342
public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generationOptions,
@@ -357,7 +369,7 @@ public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
357369
* <pre>{@code
358370
* {
359371
* id: String (Required)
360-
* status: String (Required)
372+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
361373
* error (Optional): {
362374
* code: String (Required)
363375
* message: String (Required)
@@ -366,6 +378,9 @@ public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
366378
* (recursive schema, see above)
367379
* ]
368380
* }
381+
* result (Optional): {
382+
* data: String (Required)
383+
* }
369384
* }
370385
* }</pre>
371386
*
@@ -375,7 +390,7 @@ public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
375390
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
376391
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
377392
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
378-
* @return the {@link PollerFlux} for polling of status details for long running operations.
393+
* @return the {@link PollerFlux} for polling of provides status details for long running operations.
379394
*/
380395
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)
381396
public PollerFlux<PollOperationDetails, GenerationResult>
@@ -409,7 +424,7 @@ public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
409424
* <pre>{@code
410425
* {
411426
* id: String (Required)
412-
* status: String (Required)
427+
* status: String(NotStarted/Running/Succeeded/Failed/Canceled) (Required)
413428
* error (Optional): {
414429
* code: String (Required)
415430
* message: String (Required)
@@ -418,6 +433,9 @@ public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
418433
* (recursive schema, see above)
419434
* ]
420435
* }
436+
* result (Optional): {
437+
* data: String (Required)
438+
* }
421439
* }
422440
* }</pre>
423441
*
@@ -427,7 +445,7 @@ public SyncPoller<BinaryData, BinaryData> beginLongRunningRpc(BinaryData generat
427445
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
428446
* @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
429447
* @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
430-
* @return the {@link SyncPoller} for polling of status details for long running operations.
448+
* @return the {@link SyncPoller} for polling of provides status details for long running operations.
431449
*/
432450
@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)
433451
public SyncPoller<PollOperationDetails, GenerationResult> beginLongRunningRpcWithModel(BinaryData generationOptions,

0 commit comments

Comments
 (0)