Skip to content

Commit

Permalink
Add support for ARM lro options in typespec-autorest (#955)
Browse files Browse the repository at this point in the history
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Timothee Guerin <tiguerin@microsoft.com>
  • Loading branch information
3 people authored Jun 11, 2024
1 parent 42e2912 commit f63d6d7
Show file tree
Hide file tree
Showing 53 changed files with 1,474 additions and 232 deletions.
7 changes: 7 additions & 0 deletions .chronus/changes/arm-lro-opt-2024-5-5-15-31-47.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@azure-tools/typespec-azure-core"
---

Add override decorator @useFinalStateVia for lro resolution when multiple resolution pathways exist
7 changes: 7 additions & 0 deletions .chronus/changes/arm-lro-opt-2024-5-5-15-33-29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@azure-tools/typespec-azure-resource-manager"
---

Remove OpenAPI dependencies from ARM LRO templates and test LRO overrides
7 changes: 7 additions & 0 deletions .chronus/changes/arm-lro-opt-2024-5-5-19-32-9.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@azure-tools/typespec-autorest"
---

Add suppress-lro-options emitter option to control emission of x-ms-long-running-operation-options
9 changes: 9 additions & 0 deletions .chronus/changes/arm-lro-opt-2024-5-5-2-57-50.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@azure-tools/typespec-autorest"

---

- Add support for displaying lro options in typespec-autorest based on lro metadata
6 changes: 6 additions & 0 deletions docs/emitters/typespec-autorest/reference/emitter.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,9 @@ This extension is meant for debugging and should not be depended on.
**Type:** `boolean`

Create read-only property schema for lro status

### `emit-lro-options`

**Type:** `"none" | "final-state-only" | "all"`

Determine whether and how to emit x-ms-long-running-operation-options for lro resolution
18 changes: 18 additions & 0 deletions docs/libraries/azure-core/reference/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,24 @@ Used to define how to call custom polling operations for long-running operations
| --------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| targetParameter | `ModelProperty \| string` | A reference to the polling operation parameter this parameter<br />provides a value for, or the name of that parameter. The default value is the name of<br />the decorated parameter or property. |

### `@useFinalStateVia` {#@Azure.Core.useFinalStateVia}

Overrides the final state value for an operation

```typespec
@Azure.Core.useFinalStateVia(finalState: valueof "original-uri" | "operation-location" | "location" | "azure-async-operation")
```

#### Target

`Operation`

#### Parameters

| Name | Type | Description |
| ---------- | ----------------------------------------------------------------------------------------- | ----------------------------- |
| finalState | `valueof "original-uri" \| "operation-location" \| "location" \| "azure-async-operation"` | The desired final state value |

## Azure.Core.Foundations

### `@omitKeyProperties` {#@Azure.Core.Foundations.omitKeyProperties}
Expand Down
1 change: 1 addition & 0 deletions docs/libraries/azure-core/reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ npm install --save-peer @azure-tools/typespec-azure-core
- [`@pollingLocation`](./decorators.md#@Azure.Core.pollingLocation)
- [`@pollingOperation`](./decorators.md#@Azure.Core.pollingOperation)
- [`@pollingOperationParameter`](./decorators.md#@Azure.Core.pollingOperationParameter)
- [`@useFinalStateVia`](./decorators.md#@Azure.Core.useFinalStateVia)

### Interfaces

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ model Azure.ResourceManager.ArmAcceptedResponse<Message, ExtraHeaders>
The standard header for asynchronous operation polling

```typespec
model Azure.ResourceManager.ArmAsyncOperationHeader<StatusMonitor, UrlValue>
model Azure.ResourceManager.ArmAsyncOperationHeader<StatusMonitor, UrlValue, FinalResult>
```

#### Template Parameters
Expand All @@ -74,6 +74,7 @@ model Azure.ResourceManager.ArmAsyncOperationHeader<StatusMonitor, UrlValue>
| ------------- | ------------------------------------------------- |
| StatusMonitor | The status monitor type for lro polling |
| UrlValue | The value type of the Azure-AsyncOperation header |
| FinalResult | The logical final result of the operation |

#### Properties

Expand Down
12 changes: 9 additions & 3 deletions packages/samples/specs/data-plane/api-path-parameter/main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;
interface Widgets {
// Operation Status
@doc("Gets status of a Widget operation.")
@sharedRoute
getWidgetOperationStatus is Operations.GetResourceOperationStatus<Widget>;
@sharedRoute
getWidgetDeleteOperationStatus is Operations.GetResourceOperationStatus<Widget, never>;

// Widget Operations
@doc("Creates or updates a Widget asynchronously")
Expand All @@ -86,7 +89,7 @@ interface Widgets {
getWidget is Operations.ResourceRead<Widget>;

@doc("Delete a Widget asynchronously.")
@pollingOperation(Widgets.getWidgetOperationStatus)
@pollingOperation(Widgets.getWidgetDeleteOperationStatus)
deleteWidget is Operations.LongRunningResourceDelete<Widget>;

@doc("List Widget resources")
Expand All @@ -98,7 +101,10 @@ interface Widgets {

interface Manufacturers {
@doc("Gets status of a Manufacturer operation.")
getManufacturerOperationStatus is Operations.GetResourceOperationStatus<Manufacturer>;
getManufacturerDeleteOperationStatus is Operations.GetResourceOperationStatus<
Manufacturer,
never
>;

@doc("Creates or replaces a Manufacturer")
createOrReplaceManufacturer is Operations.ResourceCreateOrReplace<Manufacturer>;
Expand All @@ -107,7 +113,7 @@ interface Manufacturers {
getManufacturer is Operations.ResourceRead<Manufacturer>;

@doc("Delete a Manufacturer asynchronously.")
@pollingOperation(Manufacturers.getManufacturerOperationStatus)
@pollingOperation(Manufacturers.getManufacturerDeleteOperationStatus)
deleteManufacturer is Operations.LongRunningResourceDelete<Manufacturer>;

@doc("List Manufacturer resources")
Expand Down
6 changes: 5 additions & 1 deletion packages/samples/specs/data-plane/custom-error-type/main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ alias Operations = Azure.Core.ResourceOperations<ServiceTraits, WidgetServiceErr
interface Widgets {
// Operation Status
@doc("Gets status of a Widget operation.")
@sharedRoute
getWidgetOperationStatus is Operations.GetResourceOperationStatus<Widget>;
/** Gets the status of a Widget delete operation */
@sharedRoute
getWidgetDeleteOperationStatus is Operations.GetResourceOperationStatus<Widget, never>;

// Widget Operations
@doc("Creates or updates a Widget asynchronously")
Expand All @@ -70,7 +74,7 @@ interface Widgets {
getWidget is Operations.ResourceRead<Widget>;

@doc("Delete a Widget asynchronously.")
@pollingOperation(Widgets.getWidgetOperationStatus)
@pollingOperation(Widgets.getWidgetDeleteOperationStatus)
deleteWidget is Operations.LongRunningResourceDelete<Widget>;

@doc("List Widget resources")
Expand Down
15 changes: 11 additions & 4 deletions packages/samples/specs/data-plane/trait-versioning/main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,12 @@ alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;

interface Widgets {
// Operation Status
@sharedRoute
@doc("Gets status of a Widget operation.")
getWidgetOperationStatus is Operations.GetResourceOperationStatus<Widget>;
@doc("Gets status of a Widget delete operation.")
@sharedRoute
getWidgetDeleteOperationStatus is Operations.GetResourceOperationStatus<Widget, never>;

// Widget Operations
@doc("Creates or updates a Widget asynchronously")
Expand All @@ -81,7 +85,7 @@ interface Widgets {
getWidget is Operations.ResourceRead<Widget>;

@doc("Delete a Widget asynchronously.")
@pollingOperation(Widgets.getWidgetOperationStatus)
@pollingOperation(Widgets.getWidgetDeleteOperationStatus)
deleteWidget is Operations.LongRunningResourceDelete<Widget>;

@doc("List Widget resources")
Expand All @@ -92,8 +96,11 @@ interface Widgets {
}

interface Manufacturers {
@doc("Gets status of a Manufacturer operation.")
getManufacturerOperationStatus is Operations.GetResourceOperationStatus<Manufacturer>;
@doc("Gets status of a Manufacturer delete operation.")
getManufacturerDeleteOperationStatus is Operations.GetResourceOperationStatus<
Manufacturer,
never
>;

@doc("Creates or replaces a Manufacturer")
createOrReplaceManufacturer is Operations.ResourceCreateOrReplace<Manufacturer>;
Expand All @@ -102,7 +109,7 @@ interface Manufacturers {
getManufacturer is Operations.ResourceRead<Manufacturer>;

@doc("Delete a Manufacturer asynchronously.")
@pollingOperation(Manufacturers.getManufacturerOperationStatus)
@pollingOperation(Manufacturers.getManufacturerDeleteOperationStatus)
deleteManufacturer is Operations.LongRunningResourceDelete<Manufacturer>;

@doc("List Manufacturer resources")
Expand Down
21 changes: 14 additions & 7 deletions packages/samples/specs/data-plane/widget-manager/main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;
interface Widgets {
// Operation Status
@doc("Gets status of a Widget operation.")
@sharedRoute
getWidgetOperationStatus is Operations.GetResourceOperationStatus<Widget>;
@doc("Gets status of a Widget delete operation.")
@sharedRoute
getWidgetDeleteOperationStatus is Operations.GetResourceOperationStatus<Widget, never>;

// Widget Operations
@doc("Creates or updates a Widget asynchronously")
Expand All @@ -184,7 +188,7 @@ interface Widgets {
getWidget is Operations.ResourceRead<Widget>;

@doc("Delete a Widget asynchronously.")
@pollingOperation(Widgets.getWidgetOperationStatus)
@pollingOperation(Widgets.getWidgetDeleteOperationStatus)
deleteWidget is Operations.LongRunningResourceDelete<Widget>;

@doc("List Widget resources")
Expand All @@ -207,7 +211,7 @@ interface Widgets {
getRepairStatus is Foundations.GetOperationStatus<WidgetRepairStatusParams, WidgetRepairRequest>;

@doc("Schedule a widget for repairs.")
@pollingOperation(Widgets.getWidgetOperationStatus)
@pollingOperation(Widgets.getRepairStatus)
scheduleRepairs is Operations.LongRunningResourceAction<
Widget,
WidgetRepairRequest,
Expand All @@ -217,7 +221,7 @@ interface Widgets {

interface WidgetParts {
@doc("Gets status of a WidgetPart operation.")
getWidgetPartOperationStatus is Operations.GetResourceOperationStatus<WidgetPart>;
getWidgetPartReorderOperationStatus is Operations.GetResourceOperationStatus<WidgetPart, never>;

@doc("Creates a WidgetPart")
createWidgetPart is Operations.ResourceCreateWithServiceProvidedName<WidgetPart>;
Expand All @@ -232,7 +236,7 @@ interface WidgetParts {
listWidgetParts is Operations.ResourceList<WidgetPart>;

@doc("Reorder all parts for the widget.")
@pollingOperation(WidgetParts.getWidgetPartOperationStatus)
@pollingOperation(WidgetParts.getWidgetPartReorderOperationStatus)
reorderParts is Operations.LongRunningResourceCollectionAction<
WidgetPart,
WidgetPartReorderRequest,
Expand All @@ -241,8 +245,11 @@ interface WidgetParts {
}

interface Manufacturers {
@doc("Gets status of a Manufacturer operation.")
getManufacturerOperationStatus is Operations.GetResourceOperationStatus<Manufacturer>;
@doc("Gets status of a Manufacturer delete operation.")
getManufacturerDeleteOperationStatus is Operations.GetResourceOperationStatus<
Manufacturer,
never
>;

@doc("Creates or replaces a Manufacturer")
createOrReplaceManufacturer is Operations.ResourceCreateOrReplace<Manufacturer>;
Expand All @@ -251,7 +258,7 @@ interface Manufacturers {
getManufacturer is Operations.ResourceRead<Manufacturer>;

@doc("Delete a Manufacturer asynchronously.")
@pollingOperation(Manufacturers.getManufacturerOperationStatus)
@pollingOperation(Manufacturers.getManufacturerDeleteOperationStatus)
deleteManufacturer is Operations.LongRunningResourceDelete<Manufacturer>;

@doc("List Manufacturer resources")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,15 @@
}
}
},
"x-ms-long-running-operation-options": {
"final-state-via": "operation-location"
},
"x-ms-long-running-operation": true
}
},
"/api/{api-version}/manufacturers/{manufacturerId}/operations/{operationId}": {
"get": {
"operationId": "Manufacturers_GetManufacturerOperationStatus",
"operationId": "Manufacturers_GetManufacturerDeleteOperationStatus",
"description": "Gets status of a Manufacturer operation.",
"parameters": [
{
Expand Down Expand Up @@ -424,10 +427,6 @@
"error": {
"$ref": "#/definitions/Azure.Core.Foundations.Error",
"description": "Error object that describes the error when status is \"Failed\"."
},
"result": {
"$ref": "#/definitions/Manufacturer",
"description": "The result of the operation."
}
},
"required": [
Expand Down Expand Up @@ -773,6 +772,9 @@
}
}
},
"x-ms-long-running-operation-options": {
"final-state-via": "operation-location"
},
"x-ms-long-running-operation": true
},
"delete": {
Expand Down Expand Up @@ -886,6 +888,9 @@
}
}
},
"x-ms-long-running-operation-options": {
"final-state-via": "operation-location"
},
"x-ms-long-running-operation": true
}
},
Expand Down Expand Up @@ -958,6 +963,72 @@
}
}
},
"x-ms-paths": {
"/api/{api-version}/widgets/{widgetName}/operations/{operationId}?_overload=getWidgetDeleteOperationStatus": {
"get": {
"operationId": "Widgets_GetWidgetDeleteOperationStatus",
"description": "Resource operation status operation template.",
"parameters": [
{
"$ref": "#/parameters/ApiVersionPathParameter"
},
{
"name": "widgetName",
"in": "path",
"description": "The widget name.",
"required": true,
"type": "string"
},
{
"name": "operationId",
"in": "path",
"description": "The unique ID of the operation.",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "The request has succeeded.",
"schema": {
"type": "object",
"description": "Provides status details for long running operations.",
"properties": {
"id": {
"type": "string",
"description": "The unique ID of the operation."
},
"status": {
"$ref": "#/definitions/Azure.Core.Foundations.OperationState",
"description": "The status of the operation"
},
"error": {
"$ref": "#/definitions/Azure.Core.Foundations.Error",
"description": "Error object that describes the error when status is \"Failed\"."
}
},
"required": [
"id",
"status"
]
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse"
},
"headers": {
"x-ms-error-code": {
"type": "string",
"description": "String error code indicating what went wrong."
}
}
}
}
}
}
},
"definitions": {
"Azure.Core.Foundations.Error": {
"type": "object",
Expand Down
Loading

0 comments on commit f63d6d7

Please sign in to comment.