From ce0ba866a767af579ec31e5fec3c226dd18b3279 Mon Sep 17 00:00:00 2001 From: Allen Zhang Date: Wed, 3 Jul 2024 12:42:47 -0700 Subject: [PATCH 1/7] Moving x-ms-azure-resource to internal ARM decorator and update autorest emitter to still emit x-ms-azure-resource --- packages/typespec-autorest/src/openapi.ts | 4 ++++ .../typespec-autorest/test/arm/resources.test.ts | 15 +++++++++++++++ .../lib/common-types/types.tsp | 4 ++-- .../lib/private.decorators.tsp | 8 ++++++++ .../typespec-azure-resource-manager/src/index.ts | 4 +++- .../src/private.decorators.ts | 9 +++++++++ .../typespec-azure-resource-manager/src/state.ts | 1 + 7 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/typespec-autorest/src/openapi.ts b/packages/typespec-autorest/src/openapi.ts index df257b3d38..cb4c24af12 100644 --- a/packages/typespec-autorest/src/openapi.ts +++ b/packages/typespec-autorest/src/openapi.ts @@ -13,6 +13,7 @@ import { import { getArmCommonTypeOpenAPIRef, isArmCommonType, + isAzureResourceBase, } from "@azure-tools/typespec-azure-resource-manager"; import { shouldFlattenProperty } from "@azure-tools/typespec-client-generator-core"; import { @@ -1854,6 +1855,9 @@ export async function getOpenAPIForService( function attachExtensions(type: Type, emitObject: any) { // Attach any OpenAPI extensions const extensions = getExtensions(program, type); + if (isAzureResourceBase(program, type as Model)) { + emitObject["x-ms-azure-resource"] = true; + } if (getAsEmbeddingVector(program, type as Model) !== undefined) { emitObject["x-ms-embedding-vector"] = true; } diff --git a/packages/typespec-autorest/test/arm/resources.test.ts b/packages/typespec-autorest/test/arm/resources.test.ts index e71ade9be9..78783de801 100644 --- a/packages/typespec-autorest/test/arm/resources.test.ts +++ b/packages/typespec-autorest/test/arm/resources.test.ts @@ -307,3 +307,18 @@ it("emits a scalar string with decorator parameter for resource", async () => { type: "string", }); }); + +it("emits x-ms-azure-resource for resource with @azureResourceBase", async () => { + const openApi = await openApiFor(` + @armProviderNamespace + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + namespace Microsoft.Contoso; + + @doc("Widget resource") + @Azure.ResourceManager.Private.azureResourceBase + model Widget { + name: string; + } +`); + ok(openApi.definitions.Widget["x-ms-azure-resource"]); +}); diff --git a/packages/typespec-azure-resource-manager/lib/common-types/types.tsp b/packages/typespec-azure-resource-manager/lib/common-types/types.tsp index b2d5c8b19a..2bffb7175e 100644 --- a/packages/typespec-azure-resource-manager/lib/common-types/types.tsp +++ b/packages/typespec-azure-resource-manager/lib/common-types/types.tsp @@ -7,7 +7,7 @@ using Azure.Core; namespace Azure.ResourceManager.CommonTypes; /** Common fields that are returned in the response for all Azure Resource Manager resources */ -@extension("x-ms-azure-resource", true) +@Azure.ResourceManager.Private.azureResourceBase model Resource { /** Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} */ @typeChangedFrom(Versions.v4, string) @@ -60,7 +60,7 @@ model ExtensionResource extends Resource {} /** * The resource model definition containing the full set of allowed properties for a resource. Except properties bag, there cannot be a top level property outside of this set. */ -@extension("x-ms-azure-resource", true) +@Azure.ResourceManager.Private.azureResourceBase model ResourceModelWithAllowedPropertySet extends TrackedResource { /** The fully qualified resource ID of the resource that manages this resource. Indicates if this resource is managed by another Azure resource. * If this is present, complete mode deployment will not delete the resource if it is removed from the template since it is managed by another resource. */ diff --git a/packages/typespec-azure-resource-manager/lib/private.decorators.tsp b/packages/typespec-azure-resource-manager/lib/private.decorators.tsp index 7993ea6bbb..036396a14c 100644 --- a/packages/typespec-azure-resource-manager/lib/private.decorators.tsp +++ b/packages/typespec-azure-resource-manager/lib/private.decorators.tsp @@ -66,3 +66,11 @@ extern dec defaultResourceKeySegmentName( * Note, this is intended for internal use only for now. */ extern dec enforceConstraint(target: Operation | Model, sourceType: Model, constraintType: Model); + +/** + * This decorator is used to identify Azure Resource Manager resource. In generated + * swagger definition, it will be marked with `x-ms-azure-resource`. + * + * It is *not* meant to be used directly by a spec author, + */ +extern dec azureResourceBase(target: Model); diff --git a/packages/typespec-azure-resource-manager/src/index.ts b/packages/typespec-azure-resource-manager/src/index.ts index 1109e9bf1d..c7041b65b8 100644 --- a/packages/typespec-azure-resource-manager/src/index.ts +++ b/packages/typespec-azure-resource-manager/src/index.ts @@ -8,8 +8,8 @@ export { getArmCommonTypesVersion, getArmCommonTypesVersions, isArmCommonType, - type ArmCommonTypesResolutionOptions, type ArmCommonTypeVersions, + type ArmCommonTypesResolutionOptions, } from "./common-types.js"; export * from "./namespace.js"; @@ -19,6 +19,8 @@ export * from "./resource.js"; export { $lib } from "./lib.js"; export { $linter } from "./linter.js"; +export { isAzureResourceBase } from "./private.decorators.js"; + export const $flags = definePackageFlags({ decoratorArgMarshalling: "new", }); diff --git a/packages/typespec-azure-resource-manager/src/private.decorators.ts b/packages/typespec-azure-resource-manager/src/private.decorators.ts index 39afe7bc27..04dd6d39ac 100644 --- a/packages/typespec-azure-resource-manager/src/private.decorators.ts +++ b/packages/typespec-azure-resource-manager/src/private.decorators.ts @@ -350,3 +350,12 @@ function hasProperty(program: Program, model: Model): boolean { if (model.baseModel) return hasProperty(program, model.baseModel); return false; } + +export function $azureResourceBase(context: DecoratorContext, resourceType: Model) { + context.program.stateMap(ArmStateKeys.azureResourceBase).set(resourceType, true); +} + +export function isAzureResourceBase(program: Program, resourceType: Model): boolean { + const resourceBase = program.stateMap(ArmStateKeys.azureResourceBase).get(resourceType); + return resourceBase ?? false; +} diff --git a/packages/typespec-azure-resource-manager/src/state.ts b/packages/typespec-azure-resource-manager/src/state.ts index c26affb22b..e8d5d68922 100644 --- a/packages/typespec-azure-resource-manager/src/state.ts +++ b/packages/typespec-azure-resource-manager/src/state.ts @@ -22,6 +22,7 @@ export const ArmStateKeys = { armBuiltInResource: azureResourceManagerCreateStateSymbol("armExternalResource"), // private.decorator.ts + azureResourceBase: azureResourceManagerCreateStateSymbol("azureResourceBase"), armCommonDefinitions: azureResourceManagerCreateStateSymbol("armCommonDefinitions"), armCommonParameters: azureResourceManagerCreateStateSymbol("armCommonParameters"), armCommonTypesVersions: azureResourceManagerCreateStateSymbol("armCommonTypesVersions"), From 2ddbcc97f9f3b9a6bfbfa7365b5c442f9695d79c Mon Sep 17 00:00:00 2001 From: Allen Zhang Date: Wed, 3 Jul 2024 12:45:20 -0700 Subject: [PATCH 2/7] Change log --- .../azhang_RemoveAzureResource-2024-6-3-12-45-15.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md diff --git a/.chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md b/.chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md new file mode 100644 index 0000000000..d33609f7a6 --- /dev/null +++ b/.chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md @@ -0,0 +1,8 @@ +--- +changeKind: internal +packages: + - "@azure-tools/typespec-autorest" + - "@azure-tools/typespec-azure-resource-manager" +--- + +Removed direct reference to OpenAPI extension `x-ms-azure-resource` in ARM library and replaced with `@Azure.ResourceManager.Private.azureResourceBase` decorator. It is only used internally on base resource types. `autorest` emitter has been updated to check the decorator and still emit `x-ms-azure-resource` extension in swagger. \ No newline at end of file From 306cbae68eb3737de605fd818c4f11eb8906a4b1 Mon Sep 17 00:00:00 2001 From: Allen Zhang Date: Wed, 3 Jul 2024 14:36:36 -0700 Subject: [PATCH 3/7] update function name. --- packages/typespec-autorest/src/openapi.ts | 4 ++-- packages/typespec-azure-resource-manager/src/index.ts | 2 +- .../src/private.decorators.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/typespec-autorest/src/openapi.ts b/packages/typespec-autorest/src/openapi.ts index cb4c24af12..52c1d06557 100644 --- a/packages/typespec-autorest/src/openapi.ts +++ b/packages/typespec-autorest/src/openapi.ts @@ -13,7 +13,7 @@ import { import { getArmCommonTypeOpenAPIRef, isArmCommonType, - isAzureResourceBase, + isAzureResource, } from "@azure-tools/typespec-azure-resource-manager"; import { shouldFlattenProperty } from "@azure-tools/typespec-client-generator-core"; import { @@ -1855,7 +1855,7 @@ export async function getOpenAPIForService( function attachExtensions(type: Type, emitObject: any) { // Attach any OpenAPI extensions const extensions = getExtensions(program, type); - if (isAzureResourceBase(program, type as Model)) { + if (isAzureResource(program, type as Model)) { emitObject["x-ms-azure-resource"] = true; } if (getAsEmbeddingVector(program, type as Model) !== undefined) { diff --git a/packages/typespec-azure-resource-manager/src/index.ts b/packages/typespec-azure-resource-manager/src/index.ts index c7041b65b8..81448b476b 100644 --- a/packages/typespec-azure-resource-manager/src/index.ts +++ b/packages/typespec-azure-resource-manager/src/index.ts @@ -19,7 +19,7 @@ export * from "./resource.js"; export { $lib } from "./lib.js"; export { $linter } from "./linter.js"; -export { isAzureResourceBase } from "./private.decorators.js"; +export { isAzureResource } from "./private.decorators.js"; export const $flags = definePackageFlags({ decoratorArgMarshalling: "new", diff --git a/packages/typespec-azure-resource-manager/src/private.decorators.ts b/packages/typespec-azure-resource-manager/src/private.decorators.ts index 04dd6d39ac..c4baaa398f 100644 --- a/packages/typespec-azure-resource-manager/src/private.decorators.ts +++ b/packages/typespec-azure-resource-manager/src/private.decorators.ts @@ -355,7 +355,7 @@ export function $azureResourceBase(context: DecoratorContext, resourceType: Mode context.program.stateMap(ArmStateKeys.azureResourceBase).set(resourceType, true); } -export function isAzureResourceBase(program: Program, resourceType: Model): boolean { - const resourceBase = program.stateMap(ArmStateKeys.azureResourceBase).get(resourceType); - return resourceBase ?? false; +export function isAzureResource(program: Program, resourceType: Model): boolean { + const isResourceBase = program.stateMap(ArmStateKeys.azureResourceBase).get(resourceType); + return isResourceBase ?? false; } From 4e52238fe3711cddd3d909658629abb5fc08902a Mon Sep 17 00:00:00 2001 From: Allen Zhang Date: Mon, 8 Jul 2024 10:21:41 -0700 Subject: [PATCH 4/7] update format --- .../typespec-azure-resource-manager/CHANGELOG.md | 15 ++++++++------- .../typespec-azure-resource-manager/src/index.ts | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/typespec-azure-resource-manager/CHANGELOG.md b/packages/typespec-azure-resource-manager/CHANGELOG.md index fa32d04822..35e4ac2d81 100644 --- a/packages/typespec-azure-resource-manager/CHANGELOG.md +++ b/packages/typespec-azure-resource-manager/CHANGELOG.md @@ -19,14 +19,12 @@ - [#811](https://github.com/Azure/typespec-azure/pull/811) Remove dependency on `typespec-autorest` emitter - [#432](https://github.com/Azure/typespec-azure/pull/432) Add support for values - ## 0.42.1 ### Bug Fixes - [#868](https://github.com/Azure/typespec-azure/pull/868) Changing back `ManagedServiceIdentity.userAssignedIdentities` back to `Record Date: Mon, 8 Jul 2024 13:43:46 -0700 Subject: [PATCH 5/7] update doc --- .../changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md b/.chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md index d33609f7a6..e1855108c4 100644 --- a/.chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md +++ b/.chronus/changes/azhang_RemoveAzureResource-2024-6-3-12-45-15.md @@ -1,8 +1,8 @@ --- -changeKind: internal +changeKind: feature packages: - "@azure-tools/typespec-autorest" - "@azure-tools/typespec-azure-resource-manager" --- -Removed direct reference to OpenAPI extension `x-ms-azure-resource` in ARM library and replaced with `@Azure.ResourceManager.Private.azureResourceBase` decorator. It is only used internally on base resource types. `autorest` emitter has been updated to check the decorator and still emit `x-ms-azure-resource` extension in swagger. \ No newline at end of file +Removed direct reference to OpenAPI extension `x-ms-azure-resource` in ARM library and replaced with `@Azure.ResourceManager.Private.azureResourceBase` decorator. It is only used internally on base resource types. `autorest` emitter has been updated to check the decorator and still emit `x-ms-azure-resource` extension in swagger. From 0003723d2855d340406a075faa7267ac3117c22d Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Mon, 8 Jul 2024 14:04:29 -0700 Subject: [PATCH 6/7] Format --- packages/typespec-azure-resource-manager/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typespec-azure-resource-manager/src/index.ts b/packages/typespec-azure-resource-manager/src/index.ts index f680c139cf..7d458b5e47 100644 --- a/packages/typespec-azure-resource-manager/src/index.ts +++ b/packages/typespec-azure-resource-manager/src/index.ts @@ -8,8 +8,8 @@ export { getArmCommonTypesVersion, getArmCommonTypesVersions, isArmCommonType, - type ArmCommonTypeVersions, type ArmCommonTypesResolutionOptions, + type ArmCommonTypeVersions, } from "./common-types.js"; export { isAzureResource } from "./private.decorators.js"; From 4fe18a6cdcc28b8a7510e28efc8c99d9f881638b Mon Sep 17 00:00:00 2001 From: Allen Zhang Date: Tue, 9 Jul 2024 12:26:00 -0700 Subject: [PATCH 7/7] Fixing sample generation failure --- packages/samples/common-types/src/types.tsp | 3 +++ .../lib/common-types/types-ref.tsp | 3 +++ .../typespec-azure-resource-manager/lib/common-types/types.tsp | 2 -- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/samples/common-types/src/types.tsp b/packages/samples/common-types/src/types.tsp index 853ab46349..a5f7a68350 100644 --- a/packages/samples/common-types/src/types.tsp +++ b/packages/samples/common-types/src/types.tsp @@ -20,3 +20,6 @@ op registerParams( ): void; @@extension(ErrorDetail.details, "x-ms-identifiers", ["message", "target"]); + +@@extension(Resource, "x-ms-azure-resource", true); +@@extension(ResourceModelWithAllowedPropertySet, "x-ms-azure-resource", true); diff --git a/packages/typespec-azure-resource-manager/lib/common-types/types-ref.tsp b/packages/typespec-azure-resource-manager/lib/common-types/types-ref.tsp index 09cadfb7ba..eb04399e3d 100644 --- a/packages/typespec-azure-resource-manager/lib/common-types/types-ref.tsp +++ b/packages/typespec-azure-resource-manager/lib/common-types/types-ref.tsp @@ -7,6 +7,9 @@ using Azure.ResourceManager.CommonTypes.Private; namespace Azure.ResourceManager.CommonTypes; +@@azureResourceBase(Resource); +@@azureResourceBase(ResourceModelWithAllowedPropertySet); + /** Common resource fields that are returned in the response for all Azure Resource Manager resources. */ @@armCommonDefinition(Resource, "Resource", Azure.ResourceManager.CommonTypes.Versions.v3); @@armCommonDefinition(Resource, "Resource", Azure.ResourceManager.CommonTypes.Versions.v4); diff --git a/packages/typespec-azure-resource-manager/lib/common-types/types.tsp b/packages/typespec-azure-resource-manager/lib/common-types/types.tsp index 327a6d82ac..109a64091d 100644 --- a/packages/typespec-azure-resource-manager/lib/common-types/types.tsp +++ b/packages/typespec-azure-resource-manager/lib/common-types/types.tsp @@ -7,7 +7,6 @@ using Azure.Core; namespace Azure.ResourceManager.CommonTypes; /** Common fields that are returned in the response for all Azure Resource Manager resources */ -@Azure.ResourceManager.Private.azureResourceBase model Resource { /** Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} */ @typeChangedFrom(Versions.v4, string) @@ -60,7 +59,6 @@ model ExtensionResource extends Resource {} /** * The resource model definition containing the full set of allowed properties for a resource. Except properties bag, there cannot be a top level property outside of this set. */ -@Azure.ResourceManager.Private.azureResourceBase model ResourceModelWithAllowedPropertySet extends TrackedResource { /** The fully qualified resource ID of the resource that manages this resource. Indicates if this resource is managed by another Azure resource. * If this is present, complete mode deployment will not delete the resource if it is removed from the template since it is managed by another resource. */