Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Pan Shao committed Sep 5, 2024
1 parent 2ae1e2f commit 848bac4
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { getResourceDataSchema, OperationSet } from "./operation-set";
import { getPagingItemType } from "./resource-equivalent";
import { getResourceType, getScopePath, isScopedSegment, pathIncludes } from "./utils";
import { lastWordToSingular } from "../utils/strings";

const extensionMethodCache = new WeakMap<OperationSet, [Operation, string][]>();
const resourceCollectionMethodCache = new WeakMap<OperationSet, Operation[]>();
Expand Down Expand Up @@ -69,7 +70,7 @@ export function setParentOfOtherOperation(
requestPath: string,
operationSets: OperationSet[],
): boolean {
const candidates: OperationSet[] = operationSets.filter((o) => pathIncludes(requestPath, o.RequestPath));
const candidates: OperationSet[] = operationSets.filter((o) => pathIncludes(requestPath, o.SingletonRequestPath ?? o.RequestPath));
if (candidates.length === 0) return false;

const bestOne = candidates.sort((a, b) => b.RequestPath.split("/").length - a.RequestPath.split("/").length)[0];
Expand Down Expand Up @@ -152,11 +153,11 @@ export function getParents(requestPath: string, operationSets: OperationSet[]):
if (parentPath === ResourceGroupPath) return ["ResourceGroupResource"];
if (parentPath === SubscriptionPath) return ["SubscriptionResource"];
if (parentPath === TenantPath) return ["TenantResource"];
const operationSet = operationSets.find((set) => set.RequestPath === parentPath);
const operationSet = operationSets.find((set) => (set.SingletonRequestPath ?? set.RequestPath) === parentPath);
if (operationSet === undefined) {
return getParents(parentPath, operationSets);
}
return [getResourceDataSchema(operationSet!)!];
return [lastWordToSingular(getResourceDataSchema(operationSet!)!)];
}

function getScopeResourceType(path: string): string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ArraySchema, HttpMethod, isObjectSchema, Operation, SchemaResponse } from "@autorest/codemodel";
import { isArraySchema, isResponseSchema } from "../utils/schemas";
import { isArraySchema, isConstantSchema, isResponseSchema } from "../utils/schemas";
import { ProvidersSegment } from "./constants";
import { isResource } from "./resource-equivalent";

export interface OperationSet {
RequestPath: string;
Operations: Array<Operation>;
SingletonRequestPath: string | undefined;
}

const resourceDataSchemaCache = new WeakMap<OperationSet, string | undefined>();
Expand Down Expand Up @@ -56,6 +57,30 @@ function checkEvenSegments(path: string): boolean {
return segments.length % 2 === 0;
}

export function populateSingletonRequestPath(set: OperationSet): void {
const updatedSegments: string[] = [];
const segments = set.RequestPath.split("/");
for (const segment of segments) {
if (segment.match(/^\{\w+\}$/) === null) {
updatedSegments.push(segment);
}
else {
const keyName = segment.replace(/^\{(\w+)\}$/, "$1");
const resourceKeyParameter = set.Operations[0].parameters?.find(p => p.language.default.name === keyName);
if (resourceKeyParameter === undefined) throw `Cannot find parameter ${keyName}`;

if (!isConstantSchema(resourceKeyParameter.schema)) {
updatedSegments.push(segment);
}
else {
const value = resourceKeyParameter.schema.value.value;
updatedSegments.push(value);
}
}
}
set.SingletonRequestPath = updatedSegments.join("/");
}

export function findOperation(set: OperationSet, method: HttpMethod): Operation | undefined {
return set.Operations.find((o) => o.requests![0].protocol.http?.method === method);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
setParentOfOtherOperation,
setParentOfResourceCollectionOperation,
} from "./find-parent";
import { findOperation, getResourceDataSchema, OperationSet } from "./operation-set";
import { findOperation, getResourceDataSchema, OperationSet, populateSingletonRequestPath } from "./operation-set";
import { getPagingItemType, isTrackedResource } from "./resource-equivalent";
import { getResourceKey, getResourceKeySegment, getResourceType, isScopedPath, isSingleton } from "./utils";

Expand All @@ -25,7 +25,7 @@ export function parseMetadata(codeModel: CodeModel): Metadata {
if (path in operationSets) {
operationSets[path].Operations.push(operation);
} else {
operationSets[path] = { RequestPath: path, Operations: [operation] };
operationSets[path] = { RequestPath: path, Operations: [operation], SingletonRequestPath: undefined };
}
}

Expand All @@ -34,8 +34,7 @@ export function parseMetadata(codeModel: CodeModel): Metadata {
const operationSet = operationSets[key];
const resourceSchemaName = getResourceDataSchema(operationSet);
if (resourceSchemaName !== undefined) {
// resourceSchemaName = lastWordToSingular(resourceSchemaName);

populateSingletonRequestPath(operationSet);
if (resourceSchemaName in operationSetsByResourceDataSchemaName) {
operationSetsByResourceDataSchemaName[resourceSchemaName].push(operationSet);
} else {
Expand Down Expand Up @@ -160,7 +159,7 @@ function buildResource(
IsSubscriptionResource: isSubscriptionResource,
IsManagementGroupResource: isManagementGroupResource,
IsExtensionResource: isScopedPath(set.RequestPath),
IsSingletonResource: isSingleton(set.RequestPath),
IsSingletonResource: isSingleton(set),
};
}

Expand Down
22 changes: 16 additions & 6 deletions packages/extensions/openapi-to-typespec/src/resource/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isConstantSchema } from "../utils/schemas";
import {
ManagementGroupPath,
ManagementGroupScopePrefix,
Expand All @@ -9,6 +10,7 @@ import {
TenantPath,
TenantScopePrefix,
} from "./constants";
import { OperationSet } from "./operation-set";

export function getResourceType(path: string): string {
const index = path.lastIndexOf(ProvidersSegment);
Expand All @@ -31,7 +33,7 @@ export function getResourceType(path: string): string {

export function getResourceKey(path: string): string {
const segments = path.split("/");
return segments[segments.length - 1].replace(/^\{(.+)\}$/, "$1");
return segments[segments.length - 1].replace(/^\{(\w+)\}$/, "$1");
}

export function getResourceKeySegment(path: string): string {
Expand Down Expand Up @@ -61,11 +63,14 @@ export function isScopedPath(path: string): boolean {
return isScopedSegment(getScopePath(path));
}

export function isSingleton(path: string): boolean {
const segments = path.split("/");
const lastSegment = segments[segments.length - 1];
const pattern = /^\{\w+\}$/;
return lastSegment.match(pattern) === null;
export function isSingleton(set: OperationSet): boolean {
const lastSegment = getLastSegment(set.RequestPath);
if (lastSegment.match(/^\{\w+\}$/) === null) return true;

const resourceKey = lastSegment.replace(/^\{(\w+)\}$/, "$1");
const resourceKeyParameter = set.Operations[0].parameters?.find(p => p.language.default.name === resourceKey);
if (resourceKeyParameter === undefined) throw `Cannot find parameter ${resourceKey}`;
return isConstantSchema(resourceKeyParameter?.schema)
}

export function pathIncludes(path1: string, path2: string): boolean {
Expand All @@ -74,3 +79,8 @@ export function pathIncludes(path1: string, path2: string): boolean {
// TO-DO: escape the variable case
return lowerPath1.includes(lowerPath2);
}

function getLastSegment(path: string): string {
const segments = path.split("/");
return segments[segments.length - 1];
}
Original file line number Diff line number Diff line change
Expand Up @@ -522,34 +522,6 @@ function convertResourceListOperations(
}
}

// add list operation for singleton resource if exists
if (resourceMetadata.IsSingletonResource) {
const swaggerOperation = getSingletonResouceListOperation(resourceMetadata);
if (swaggerOperation) {
const okResponse = swaggerOperation?.responses?.filter((o) => o.protocol.http?.statusCodes.includes("200"))?.[0];
const baseParameters = buildOperationBaseParameters(swaggerOperation, resourceMetadata);

addGeneratedResourceObjectIfNotExits(
getSchemaResponseSchemaName(okResponse) ?? "",
`ResourceListResult<${resourceMetadata.SwaggerModelName}>`,
);
converted.push({
doc: swaggerOperation.language.default.description,
kind: "ArmResourceListByParent",
name: swaggerOperation.operationId
? getOperationName(swaggerOperation.operationId)
: `listBy${resourceMetadata.Parents[0].replace(/Resource$/, "")}`,
clientDecorators: getOperationClientDecorators(swaggerOperation),
operationId: swaggerOperation.operationId,
templateParameters: baseParameters
? [resourceMetadata.SwaggerModelName, baseParameters]
: [resourceMetadata.SwaggerModelName],
examples: swaggerOperation.extensions?.["x-ms-examples"],
});
(swaggerOperation as OperationWithResourceOperationFlag).isResourceOperation = true;
}
}

return converted;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@
"IsSubscriptionResource": false,
"IsManagementGroupResource": false,
"IsExtensionResource": false,
"IsSingletonResource": false
"IsSingletonResource": true
},
"BlobContainer": {
"Name": "BlobContainer",
Expand Down Expand Up @@ -862,24 +862,6 @@
"PagingMetadata": null,
"Description": "Clears legal hold tags. Clearing the same or non-existent tag results in an idempotent operation. ClearLegalHold clears out only the specified tags in the request."
},
{
"Name": "LockImmutabilityPolicy",
"Path": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/blobServices/default/containers/{containerName}/immutabilityPolicies/default/lock",
"Method": "POST",
"OperationID": "BlobContainers_LockImmutabilityPolicy",
"IsLongRunning": false,
"PagingMetadata": null,
"Description": "Sets the ImmutabilityPolicy to Locked state. The only action allowed on a Locked policy is ExtendImmutabilityPolicy action. ETag in If-Match is required for this operation."
},
{
"Name": "ExtendImmutabilityPolicy",
"Path": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/blobServices/default/containers/{containerName}/immutabilityPolicies/default/extend",
"Method": "POST",
"OperationID": "BlobContainers_ExtendImmutabilityPolicy",
"IsLongRunning": false,
"PagingMetadata": null,
"Description": "Extends the immutabilityPeriodSinceCreationInDays of a locked immutabilityPolicy. The only action allowed on a Locked policy will be this action. ETag in If-Match is required for this operation."
},
{
"Name": "Lease",
"Path": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/blobServices/default/containers/{containerName}/lease",
Expand All @@ -900,7 +882,7 @@
}
],
"Parents": [
"StorageAccount"
"BlobServiceProperty"
],
"SwaggerModelName": "BlobContainer",
"ResourceType": "Microsoft.Storage/storageAccounts/blobServices/containers",
Expand Down Expand Up @@ -964,7 +946,26 @@
"OperationsFromSubscriptionExtension": [],
"OperationsFromManagementGroupExtension": [],
"OperationsFromTenantExtension": [],
"OtherOperations": [],
"OtherOperations": [
{
"Name": "LockImmutabilityPolicy",
"Path": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/blobServices/default/containers/{containerName}/immutabilityPolicies/default/lock",
"Method": "POST",
"OperationID": "BlobContainers_LockImmutabilityPolicy",
"IsLongRunning": false,
"PagingMetadata": null,
"Description": "Sets the ImmutabilityPolicy to Locked state. The only action allowed on a Locked policy is ExtendImmutabilityPolicy action. ETag in If-Match is required for this operation."
},
{
"Name": "ExtendImmutabilityPolicy",
"Path": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/blobServices/default/containers/{containerName}/immutabilityPolicies/default/extend",
"Method": "POST",
"OperationID": "BlobContainers_ExtendImmutabilityPolicy",
"IsLongRunning": false,
"PagingMetadata": null,
"Description": "Extends the immutabilityPeriodSinceCreationInDays of a locked immutabilityPolicy. The only action allowed on a Locked policy will be this action. ETag in If-Match is required for this operation."
}
],
"Parents": [
"BlobContainer"
],
Expand All @@ -977,7 +978,7 @@
"IsSubscriptionResource": false,
"IsManagementGroupResource": false,
"IsExtensionResource": false,
"IsSingletonResource": false
"IsSingletonResource": true
},
"FileServiceProperties": {
"Name": "FileServiceProperty",
Expand Down Expand Up @@ -1047,7 +1048,7 @@
"IsSubscriptionResource": false,
"IsManagementGroupResource": false,
"IsExtensionResource": false,
"IsSingletonResource": false
"IsSingletonResource": true
},
"FileShare": {
"Name": "FileShare",
Expand Down Expand Up @@ -1135,7 +1136,7 @@
}
],
"Parents": [
"StorageAccount"
"FileServiceProperty"
],
"SwaggerModelName": "FileShare",
"ResourceType": "Microsoft.Storage/storageAccounts/fileServices/shares",
Expand Down Expand Up @@ -1216,7 +1217,7 @@
"IsSubscriptionResource": false,
"IsManagementGroupResource": false,
"IsExtensionResource": false,
"IsSingletonResource": false
"IsSingletonResource": true
},
"StorageQueue": {
"Name": "StorageQueue",
Expand Down Expand Up @@ -1285,7 +1286,7 @@
"OperationsFromTenantExtension": [],
"OtherOperations": [],
"Parents": [
"StorageAccount"
"QueueServiceProperty"
],
"SwaggerModelName": "StorageQueue",
"ResourceType": "Microsoft.Storage/storageAccounts/queueServices/queues",
Expand Down Expand Up @@ -1366,7 +1367,7 @@
"IsSubscriptionResource": false,
"IsManagementGroupResource": false,
"IsExtensionResource": false,
"IsSingletonResource": false
"IsSingletonResource": true
},
"Table": {
"Name": "Table",
Expand Down Expand Up @@ -1435,7 +1436,7 @@
"OperationsFromTenantExtension": [],
"OtherOperations": [],
"Parents": [
"StorageAccount"
"TableServiceProperty"
],
"SwaggerModelName": "Table",
"ResourceType": "Microsoft.Storage/storageAccounts/tableServices/tables",
Expand Down
Loading

0 comments on commit 848bac4

Please sign in to comment.