From 059a9bc20c46fcd89fbf937d90c303d4f9686ceb Mon Sep 17 00:00:00 2001 From: Krzysztof Cwalina Date: Mon, 4 Nov 2024 15:04:10 -0800 Subject: [PATCH 1/3] added support for basic async APIs --- eng/Packages.Data.props | 1 + .../src/Tsp/TypeSpecWriter.cs | 18 ++++++++--- ...ure.Provisioning.CloudMachine.Tests.csproj | 3 ++ .../tests/TdkTests.cs | 32 +++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs diff --git a/eng/Packages.Data.props b/eng/Packages.Data.props index 1b9da916ed131..f0458c142220d 100644 --- a/eng/Packages.Data.props +++ b/eng/Packages.Data.props @@ -295,6 +295,7 @@ + diff --git a/sdk/provisioning/Azure.Provisioning.CloudMachine/src/Tsp/TypeSpecWriter.cs b/sdk/provisioning/Azure.Provisioning.CloudMachine/src/Tsp/TypeSpecWriter.cs index a08ba361a898e..f8beed28929d7 100644 --- a/sdk/provisioning/Azure.Provisioning.CloudMachine/src/Tsp/TypeSpecWriter.cs +++ b/sdk/provisioning/Azure.Provisioning.CloudMachine/src/Tsp/TypeSpecWriter.cs @@ -5,6 +5,7 @@ using System.IO; using System.Net; using System.Reflection; +using System.Threading.Tasks; namespace System.ClientModel.TypeSpec; public static class TypeSpecWriter @@ -104,7 +105,9 @@ private static void WriteOperation(StreamWriter writer, MethodInfo method, HashS { string httpVerb = ReadHttpVerb(method); - writer.Write($"{httpVerb} @route(\"{ToCamel(method.Name)}\") {method.Name}("); + var methodName = method.Name; + if (methodName.EndsWith("Async")) methodName = methodName.Substring(0, methodName.Length - "Async".Length); + writer.Write($"{httpVerb} @route(\"{ToCamel(methodName)}\") {methodName}("); bool first = true; foreach (var parameter in method.GetParameters()) @@ -136,11 +139,16 @@ private static void WriteOperation(StreamWriter writer, MethodInfo method, HashS } writer.WriteLine(") : {"); writer.WriteLine($" @statusCode statusCode: 200;"); - if (method.ReflectedType != typeof(void)) - writer.WriteLine($" @body response : {method.ReturnType.ToTspType()};"); + + var returnType = method.ReturnType; + if (returnType == typeof(Task)) returnType = typeof(void); + else if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>)) + returnType = returnType.GetGenericArguments()[0]; + + writer.WriteLine($" @body response : {returnType.ToTspType()};"); writer.WriteLine(" };"); - if (method.ReturnType.IsModel()) - models.Add(method.ReturnType); + if (returnType.IsModel()) + models.Add(returnType); } private static string ReadParameterLocation(ParameterInfo parameter) diff --git a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj index ac4afb158ed33..ae77672a9e8ca 100644 --- a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj +++ b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj @@ -2,6 +2,9 @@ 12 + + + diff --git a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs new file mode 100644 index 0000000000000..babdeed96ea44 --- /dev/null +++ b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable enable + +using System.Threading.Tasks; +using Azure.Provisioning.CloudMachine; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using NUnit.Framework; + +namespace Azure.CloudMachine.Tests; + +public class TdkTests +{ + [Theory] + [TestCase([new string[] { "-tsp" }])] + public void BasicTsp(string[] args) + { + CloudMachineInfrastructure.Configure(args, (cm) => + { + cm.AddEndpoints(); + }); + } +} + +internal interface IAssistantService +{ + [HttpPut] + Task UploadAsync(HttpRequest document); + Task SendAsync([FromQuery] string message); +} From 6e18cd8cbb24a8327090adcc61e2f3d988265a57 Mon Sep 17 00:00:00 2001 From: Krzysztof Cwalina Date: Mon, 4 Nov 2024 15:24:51 -0800 Subject: [PATCH 2/3] PR feedback --- .../tests/TdkTests.cs | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs index babdeed96ea44..9eb9bbd3a5b6b 100644 --- a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs +++ b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs @@ -3,8 +3,10 @@ #nullable enable +using System; +using System.ClientModel.TypeSpec; +using System.IO; using System.Threading.Tasks; -using Azure.Provisioning.CloudMachine; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using NUnit.Framework; @@ -13,15 +15,46 @@ namespace Azure.CloudMachine.Tests; public class TdkTests { - [Theory] - [TestCase([new string[] { "-tsp" }])] - public void BasicTsp(string[] args) + [Test] + public void GenerateIAssistantService() { - CloudMachineInfrastructure.Configure(args, (cm) => - { - cm.AddEndpoints(); - }); + MemoryStream stream = new(); + TypeSpecWriter.WriteServer(stream); + stream.Position = 0; + + BinaryData data = BinaryData.FromStream(stream); + Assert.AreEqual(IAssistantServiceTsp, data.ToString()); } + + private static string IAssistantServiceTsp = + """ + import "@typespec/http"; + import "@typespec/rest"; + import "@azure-tools/typespec-client-generator-core"; + + @service({ + title: "AssistantService", + }) + + namespace Azure.CloudMachine.Tests; + + using TypeSpec.Http; + using TypeSpec.Rest; + using Azure.ClientGenerator.Core; + + @client interface AssistantServiceClient { + @put @route("upload") Upload(@header contentType: "application/octet-stream", @body document: bytes) : { + @statusCode statusCode: 200; + @body response : void; + }; + @get @route("send") Send(@query message: string) : { + @statusCode statusCode: 200; + @body response : string; + }; + } + + + """; } internal interface IAssistantService From 2e45d95ceec35c34e4277fe1ad548353efa815d0 Mon Sep 17 00:00:00 2001 From: Krzysztof Cwalina Date: Mon, 4 Nov 2024 17:25:46 -0800 Subject: [PATCH 3/3] removed dependency on deprecated package --- eng/Packages.Data.props | 1 - .../tests/Azure.Provisioning.CloudMachine.Tests.csproj | 5 +---- .../Azure.Provisioning.CloudMachine/tests/TdkTests.cs | 4 +++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/eng/Packages.Data.props b/eng/Packages.Data.props index f0458c142220d..1b9da916ed131 100644 --- a/eng/Packages.Data.props +++ b/eng/Packages.Data.props @@ -295,7 +295,6 @@ - diff --git a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj index ae77672a9e8ca..681498fc5e434 100644 --- a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj +++ b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/Azure.Provisioning.CloudMachine.Tests.csproj @@ -1,10 +1,7 @@ - + 12 - - - diff --git a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs index 9eb9bbd3a5b6b..7951f968ace07 100644 --- a/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs +++ b/sdk/provisioning/Azure.Provisioning.CloudMachine/tests/TdkTests.cs @@ -8,7 +8,6 @@ using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; using NUnit.Framework; namespace Azure.CloudMachine.Tests; @@ -63,3 +62,6 @@ internal interface IAssistantService Task UploadAsync(HttpRequest document); Task SendAsync([FromQuery] string message); } + +internal class FromQueryAttribute : Attribute { } +internal class HttpPutAttribute : Attribute { }