Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement mgmt resource #47944

Open
wants to merge 51 commits into
base: main
Choose a base branch
from
Open

Conversation

live1206
Copy link
Member

@live1206 live1206 commented Jan 23, 2025

@github-actions github-actions bot added Client This issue points to a problem in the data-plane of the library. CodeGen Issues that relate to code generation labels Jan 23, 2025
Copy link
Member

@m-nash m-nash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# temporarily disable building MgmtTypeSpec because now the generated code of this project cannot build
# Write-Host "Building BasicTypeSpec" -ForegroundColor Cyan
# Invoke-LoggedCommand "dotnet build $packageRoot/generator/TestProjects/Local/Mgmt-TypeSpec/src/MgmtTypeSpec.csproj"
Write-Host "Building BasicTypeSpec" -ForegroundColor Cyan
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have a Generate-Code.ps1 here? Shouldn't we be using /eng/packages/http-client-csharp/eng/scripts/Generate.ps1 which follows the pattern of ms/tsp as well?

Copy link
Member Author

@live1206 live1206 Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/eng/packages/*/eng/scripts was moved to /eng/scripts in #46511 by @hallipr.
Since we have more logic in /eng/packages/http-client-csharp/eng/scripts/Generate.ps1 now, I will add Mgmt-TypeSpec generation to it in this PR.
Then, we can sync with @hallipr if it should be moved to /eng/scripts

{
// TODO: use _clientProvider.CanonicalView instead when it implements BuildMethods
MethodProvider[] methods = [.. _clientProvider.Methods, .. _clientProvider.CustomCodeView?.Methods ?? []];
return methods.Single(m => m.Signature.Name.Equals(isAsync ? $"{operation.Name}Async" : operation.Name, StringComparison.OrdinalIgnoreCase) && m.Signature.Parameters.Any(p => p.Type.Equals(typeof(CancellationToken))));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be operation.Name.ToCleanName() instead of operation.Name. We need to expose StringExtension.ToCleanName

dmnorc pushed a commit to dmnorc/typespec that referenced this pull request Feb 18, 2025
So that, we can get the corresponding RestClientProvider while
generating Resource in Azure plugin.
Corresponding PR in Azure plugin:
Azure/azure-sdk-for-net#47944
@live1206 live1206 force-pushed the implement-mgmt-resource branch from 0d47984 to af9bd9c Compare February 19, 2025 00:34
@live1206 live1206 requested a review from Copilot February 19, 2025 01:02
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 30 out of 45 changed files in this pull request and generated 2 comments.

Files not reviewed (15)
  • eng/Packages.Data.props: Language not supported
  • eng/packages/http-client-csharp/eng/scripts/Generate.ps1: Language not supported
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Properties/launchSettings.json: Language not supported
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Providers/MgmtLongRunningOperationProvider.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Providers/ResourceDataSerializationProvider.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Utilities/OperationExtensions.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/RestClientVisitor.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Mgmt/Models/OperationSet.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Providers/ResourceDataProvider.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Providers/Abstraction/HttpPipelineProvider.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/AzureClientPlugin.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/AzureOutputLibrary.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Providers/ResourceProvider.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Utilities/ResourceDetection.cs: Evaluated as low risk
  • eng/packages/http-client-csharp/generator/Azure.Generator/src/Providers/OperationSourceProvider.cs: Evaluated as low risk
Comments suppressed due to low confidence (2)

eng/packages/http-client-csharp/generator/Azure.Generator/src/Utilities/MethodExtensions.cs:1

  • The copyright symbol is not correctly displayed. It should be corrected to '©'.
// Copyright (c) Microsoft Corporation. All rights reserved.

eng/packages/http-client-csharp/generator/Azure.Generator/src/Mgmt/Models/RequestPath.cs:101

  • The diff should be constructed using a delimiter. Change to: diff = new RequestPath(string.Join("/", other._segments.Skip(Count)));
diff = new RequestPath(string.Join("", other._segments.Skip(Count)));


namespace Azure.Generator.Providers
{
internal class ResourceProvider : TypeProvider
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets call this ResourceClientProvider and see if we can inherit from ClientProvider.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As offline discussed, we would like to reorg the rest clients, operation clients and resource clients. So that, the structure of mgmt resource clients are similar to the DPG clients.

@@ -174,7 +174,7 @@ private ConstructorProvider BuildInitializationConstructor()
skipApiVersionOverrideParameter,
apiVersionOverrideValueParameter,
};
var signature = new ConstructorSignature(Type, $"", MethodSignatureModifiers.Internal, parameters, null);
var signature = new ConstructorSignature(Type, $"", MethodSignatureModifiers.Internal, parameters);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason this class is prefixed with Mgmt? I think Dpg and Mpg LROs work the same other than the type that gets used ArmOperation vs Operation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, it only contains logic for Mgmt, rename it to LongRunningOperationProvider.

private Dictionary<string, OperationSet> _pathToOperationSetMap;
private Dictionary<string, HashSet<OperationSet>> _resourceDataBySpecNameMap;
//TODO: Move these to InputLibrary instead
private Dictionary<RequestPath, OperationSet> _pathToOperationSetMap;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of code in here that is mgmt specific and it starts to get difficult to tell which is which have we considered a mgmt plugin?

Copy link
Member Author

@live1206 live1206 Feb 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most likely.
Given I am fully working with MPG now, I think it would be better to split them when we have more implementation on DPG, then we can clarify the things in common for both.

@@ -30,6 +31,9 @@ public class AzureClientPlugin : ScmCodeModelPlugin
public override AzureOutputLibrary OutputLibrary => _azureOutputLibrary ??= new();

internal ResourceDetection ResourceDetection { get; } = new();
internal ParentDetection ParentDetection { get; } = new();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't your parent just a property on the client from typespec?

Copy link
Member Author

@live1206 live1206 Feb 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For TypeSpec, we should be able to get the resource hierarchy directly via #48281.
The resource detection logic is mainly for swagger input.
For now, given getArmResources API is not ready for integration. We use it as a temporary workaround.

Eventually, when we have the native way ready, we should get rid of them. And the resource detection should be part of the M4 output conversion to tspCodeModel.json in autorest.csharp.
Added TODO to remove them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As offline discussed, we need to clarify the contract of input types containing the resource hierarchy. And it should be an extensible way of holding it in Azure plugin only.
Then, we can put the temp workaround of resource detection close to the input instead of output.

TryGetApiVersion(ResourceType, out string fooApiVersion);
_fooRestClient = new Foos(Pipeline, Endpoint, fooApiVersion);
#if DEBUG
global::MgmtTypeSpec.FooResource.ValidateResourceId(id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not getting reduced because its in an if debug?

Copy link
Member Author

@live1206 live1206 Feb 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, you were talking about the namespace not reduced.
Yes. I tried to remove the debug block, the namespace was simplified.

Copy link
Member Author

@live1206 live1206 Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raise issue in MGC to fix this
we can replace it with Debug.Assert here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug.Assert can't be used here, it needs a bool condition input, but this method is void.
Use [Conditional("DEBUG")] in the method signature instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

microsoft/typespec#6160 to track the issue in MGC

namespace Samples
{
/// <summary></summary>
public partial class ResponseTypeResource : global::Azure.ResourceManager.ArmResource
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets trim this down to at most 1 method validation at a time. Otherwise this test will be susceptible to any change in generation of any portion of a resource

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to write a method of TypeProvider?
As I can see, there is no public API from TypeProviderWriter. Do we want to expose such API?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separated the tests for ResourceClientProvider.
And after exposing AzureOutputLibrary.CreateResourceCore, I realized that we need to simplify the creation of ResourceClientProvider. And it ties to the contract of Input types from MGC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Client This issue points to a problem in the data-plane of the library. CodeGen Issues that relate to code generation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Generate OperationSource in Azure plugin Implement ResourceProvdier
4 participants