diff --git a/doc/DataPlaneCodeGeneration/AzureSDKCodeGeneration_DataPlane_Quickstart.md b/doc/DataPlaneCodeGeneration/AzureSDKCodeGeneration_DataPlane_Quickstart.md index c07587755827..2a280ef0ff99 100644 --- a/doc/DataPlaneCodeGeneration/AzureSDKCodeGeneration_DataPlane_Quickstart.md +++ b/doc/DataPlaneCodeGeneration/AzureSDKCodeGeneration_DataPlane_Quickstart.md @@ -61,7 +61,7 @@ sdk\\\CHANGELOG.md - `` - Should be the short name for the azure service. e.g. deviceupdate - `` - Should be the name of the shipping package, or an abbreviation that distinguishes the given shipping artifact for the given service. It will be `Azure..`, e.g. Azure.IoT.DeviceUpdate -We will use dotnet project template [Azure.ServiceTemplate.Template](https://github.com/Azure/azure-sdk-for-net/blob/3ac301ac6435c818ad7a9946ab1c4023cee236ff/eng/templates) to automatically create the project. +We will use dotnet project template [Azure.Template](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template) to automatically create the project. You can run `eng\scripts\automation\Invoke-DataPlaneGenerateSDKPackage.ps1` to generate the starting SDK client library package directly as following: @@ -80,12 +80,13 @@ pwsh /home/azure-sdk-for-net/eng/scripts/automation/Invoke-DataPlaneGenerateSDKP - For `- namespace`, please use one of the pre-approved namespace groups on the [.NET Azure SDK Guidelines Approved Namespaces list](https://azure.github.io/azure-sdk/dotnet_introduction.html#dotnet-namespaces-approved-list). This value will also provide the name for the shipped package, and should be of the form `Azure..`. - `-inputfiles` takes the address of the Open API spec files, separated by semicolon if there is more than one file. The Open API spec file can be local file, e.g. ./swagger/compute.json, or the web address of the file in the `azure-rest-api-specs` repo. When pointing to a file in the `azure-rest-api-specs` repo, make sure to include the commit id in the URI, i.e. `https://github.com/Azure/azure-rest-api-specs/blob/73a0fa453a93bdbe8885f87b9e4e9fef4f0452d0/specification/webpubsub/data-plane/WebPubSub/stable/2021-10-01/webpubsub.json`. This ensures that you can choose the time to upgrade to new swagger file versions. - `-readme` takes the address of the readme configuration file. The configuration can be local file, e.g. ./swagger/readme.md or the web address of the file in the `azure-rest-api-specs` repo, i.e. `https://github.com/Azure/azure-rest-api-specs/blob/23dc68e5b20a0e49dd3443a4ab177d9f2fcc4c2b/specification/deviceupdate/data-plane/readme.md` +- You need to provide one of `-inputfiles` and `-readme` parameters. If you provide both, `-inputfiles` will be ignored. - `-securityScope` designates the authentication scope to use if your library supports **Token Credential** authentication. - `-securityHeaderName` designates the key to use if your library supports **Azure Key Credential** authentication. When you run the `eng\scripts\automation\Invoke-DataPlaneGenerateSDKPackage.ps1` script, it will: -- Create a project folder, install template files from `eng/templates/Azure.ServiceTemplate.Template`, and create `.csproj` and `.sln` files for your new library. +- Create a project folder, install template files from `sdk/template/Azure.Template`, and create `.csproj` and `.sln` files for your new library. These files are created following the guidance for the [Azure SDK Repo Structure](https://github.com/Azure/azure-sdk/blob/master/docs/policies/repostructure.md). @@ -111,8 +112,7 @@ Here is the step by step process to add tests:requirements - Add other client parameters in `ClientTestEnvironment.cs` - Update `ClientTest.cs`. - - Comment-out the 'CreateClient' method, and update the new `Client` statement. - - remove all the template project tests, and write the tests according to the commented Test method template. Please refer to [Using the TestFramework](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core.TestFramework/README.md) to add tests. + - Please refer to [Using the TestFramework](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core.TestFramework/README.md) to add tests. **Note**: @@ -131,13 +131,13 @@ You will update all the `Sample_.md` and README.md file ### Snippets -Snippets are the great way to reuse the sample code. Snippets allow us to verify that the code in our samples and READMEs is always up to date, and passes unit tests. We have added the snippet [here](https://github.com/Azure/azure-sdk-for-net/blob/3ac301ac6435c818ad7a9946ab1c4023cee236ff/eng/templates/Azure.ServiceTemplate.Template/tests/Samples/Sample1_CreateResource.cs#L32) in a sample and used it in the [README](https://github.com/Azure/azure-sdk-for-net/blob/3ac301ac6435c818ad7a9946ab1c4023cee236ff/eng/templates/Azure.ServiceTemplate.Template/README.md#create-resource). Please refer to [Updating Sample Snippets](https://github.com/Azure/azure-sdk-for-net/blob/main/CONTRIBUTING.md#updating-sample-snippets) to add snippets in your samples. +Snippets are the great way to reuse the sample code. Snippets allow us to verify that the code in our samples and READMEs is always up to date, and passes unit tests. We have added the snippet [here](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorld.cs#L21) in a sample and used it in the [README](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/README.md#get-secret). Please refer to [Updating Sample Snippets](https://github.com/Azure/azure-sdk-for-net/blob/main/CONTRIBUTING.md#updating-sample-snippets) to add snippets in your samples. ### README README.md file instructions are listed in `Azure../README.md` file. Please add/update the README.md file as per your library. -**Learn more:** to understand more about README, see the [README.md](https://github.com/Azure/azure-sdk-for-net/blob/3ac301ac6435c818ad7a9946ab1c4023cee236ff/eng/templates/Azure.ServiceTemplate.Template/README.md). Based on that [here](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/keyvault/Azure.Security.KeyVault.Keys/README.md) is an example. +**Learn more:** to understand more about README, see the [README.md](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/README.md). Based on that [here](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/keyvault/Azure.Security.KeyVault.Keys/README.md) is an example. ### Changelog @@ -151,7 +151,7 @@ You can add convienice APIs by adding a customization layer on top of the genera If other modifications are needed to the generated API, you can consider making them directly to the Open API specification, which will have the benefit of making the changes to the library in all languages you generate the library in. As a last resort, you can add modifications with swagger transforms in the `autorest.md` file. [AnomalyDetector autorest.md](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/anomalydetector/Azure.AI.AnomalyDetector/src/autorest.md) shows and example of how this can be accomplished. -Once you've made changes to the public API, you will need to run the `eng\scripts\Export-API.ps1` script to update the public API listing. This will generate a file in the library's directory similar to the example found in [eng\templates\Azure.ServiceTemplate.Template\api\Azure.ServiceTemplate.Template.netstandard2.0.cs](https://github.com/Azure/azure-sdk-for-net/blob/bb0fbccfc33dd27d1ec6f0870022824d47181e61/sdk/template-dpg/Azure.ServiceTemplate.Template/api/Azure.ServiceTemplate.Template.netstandard2.0.cs). +Once you've made changes to the public API, you will need to run the `eng\scripts\Export-API.ps1` script to update the public API listing. This will generate a file in the library's directory similar to the example found in [sdk\template\Azure.Template\api\Azure.Template.netstandard2.0.cs](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/api/Azure.Template.netstandard2.0.cs). e.g. Running the script for a project in `sdk\deviceupdate` would look like this: diff --git a/eng/scripts/automation/GenerateAndBuildLib.ps1 b/eng/scripts/automation/GenerateAndBuildLib.ps1 index 88792a9778a0..34df6b2e388b 100644 --- a/eng/scripts/automation/GenerateAndBuildLib.ps1 +++ b/eng/scripts/automation/GenerateAndBuildLib.ps1 @@ -1,5 +1,5 @@ #Requires -Version 7.0 - +$CI_YAML_FILE = "ci.yml" function Get-SwaggerInfo() { param( @@ -85,6 +85,30 @@ function Update-AutorestConfigFile() { exit 1 } } + +function Update-CIYmlFile() { + param ( + [string]$ciFilePath, + [string]$artifact + ) + if (Test-Path -Path $ciFilePath) { + $packageRex = "name *: $artifact" + if ((Get-Content $ciFilePath | Select-String -Pattern $packageRex).Matches.Success) { + Write-Host "CI already enabled." + } else { + $safeName = $artifact.Replace('.', '') + $artifactsBlockRex = "Artifacts *:" + $startNum = (Get-Content $ciFilePath | Select-String -Pattern $artifactsBlockRex).LineNumber[0] + $fileContent = Get-Content -Path $ciFilePath + $fileContent[$startNum - 1] += ([Environment]::NewLine + " - " + "name: $artifact" + [Environment]::NewLine + " safeName: $safeName") + $fileContent | Set-Content $ciFilePath + } + } else { + Write-Error "ci.yml doesn't exist." + exit 1 + } +} + function New-DataPlanePackageFolder() { param( [string]$service, @@ -103,13 +127,18 @@ function New-DataPlanePackageFolder() { $inputfile = "" $fileArray = $inputfiles.Split(";") if (($inputfiles -ne "") -And ($fileArray.Length -gt 0)) { - $inputfile = "- " + $fileArray[0]; - for ($i = 1; $i -lt $fileArray.Count ; $i++) { + for ($i = 0; $i -lt $fileArray.Count ; $i++) { $inputfile = $inputfile + [Environment]::NewLine + "- " + $fileArray[$i] } } + $serviceFolder = (Join-Path $sdkPath "sdk" $service) + if (!(Test-Path -Path $serviceFolder)) { + Write-Host "service folder does not exist! create the folder $serviceFolder" + New-Item -Path $serviceFolder -ItemType Directory + } $projectFolder=(Join-Path $sdkPath "sdk" $service $namespace) + $ciymlFilePath =(Join-Path $sdkPath "sdk" $service $CI_YAML_FILE) $apifolder = (Join-Path $projectFolder "api") Write-Host "projectFolder:$projectFolder, apifolder:$apifolder" if ((Test-Path -Path $projectFolder) -And (Test-Path -Path $apifolder)) { @@ -117,27 +146,31 @@ function New-DataPlanePackageFolder() { # update the input-file url if needed. $file = (Join-Path $projectFolder "src" $AUTOREST_CONFIG_FILE) Update-AutorestConfigFile -autorestFilePath $file -inputfile $inputfile -readme $readme + Update-CIYmlFile -ciFilePath $ciymlFilePath -artifact $namespace } else { Write-Host "Path doesn't exist. create template." if ($inputfile -eq "" -And $readme -eq "") { Write-Error "Error: input file should not be empty." exit 1 } - dotnet new -i $sdkPath/eng/templates/Azure.ServiceTemplate.Template + dotnet new -i $sdkPath/sdk/template Write-Host "Create project folder $projectFolder" - New-Item -Path $projectFolder -ItemType Directory - Push-Location $projectFolder + if (Test-Path -Path $projectFolder) { + Remove-Item -Path $projectFolder -ItemType Directory + } + + Push-Location $serviceFolder $namespaceArray = $namespace.Split(".") if ( $namespaceArray.Count -lt 3) { Write-Error "Error: invalid namespace name." exit 1 } - $libraryName = $namespaceArray[-1] + $clientName = $namespaceArray[-1] $groupName = $namespaceArray[1] - $dotnetNewCmd = "dotnet new dataplane --libraryName $libraryName --groupName $groupName --includeCI true --force" + $dotnetNewCmd = "dotnet new azsdkdpg --name $namespace --clientName $clientName --groupName $groupName --serviceDirectory $service --force" if ($inputfile -ne "") { - $dotnetNewCmd = $dotnetNewCmd + " --swagger $inputfile" + $dotnetNewCmd = $dotnetNewCmd + " --swagger '$inputfile'" } if ($securityScope -ne "") { $dotnetNewCmd = $dotnetNewCmd + " --securityScopes $securityScope"; @@ -147,13 +180,21 @@ function New-DataPlanePackageFolder() { $dotnetNewCmd = $dotnetNewCmd + " --securityHeaderName $securityHeaderName"; } - # dotnet new dataplane --libraryName $libraryName --swagger $inputfile --securityScopes $securityScope --securityHeaderName $securityHeaderName --includeCI true --force + if (Test-Path -Path $ciymlFilePath) { + Write-Host "ci.yml already exists. update it to include the new serviceDirectory." + Update-CIYmlFile -ciFilePath $ciymlFilePath -artifact $namespace + + $dotnetNewCmd = $dotnetNewCmd + " --includeCI false" + } + # dotnet new azsdkdpg --name $namespace --clientName $clientName --groupName $groupName --serviceDirectory $service --swagger $inputfile --securityScopes $securityScope --securityHeaderName $securityHeaderName --includeCI true --force Write-Host "Invote dotnet new command: $dotnetNewCmd" Invoke-Expression $dotnetNewCmd $file = (Join-Path $projectFolder "src" $AUTOREST_CONFIG_FILE) - Update-AutorestConfigFile -autorestFilePath $file -inputfile $inputfile -readme $readme + Update-AutorestConfigFile -autorestFilePath $file -readme $readme + Pop-Location # dotnet sln + Push-Location $projectFolder dotnet sln remove src\$namespace.csproj dotnet sln add src\$namespace.csproj dotnet sln remove tests\$namespace.Tests.csproj @@ -244,6 +285,26 @@ function Invoke-Generate() { $sdkfolder = $sdkfolder -replace "\\", "/" Push-Location $sdkfolder/src dotnet build /t:GenerateCode + if ( !$? ) { + Write-Error "Failed to generate sdk." + Pop-Location + exit 1 + } + Pop-Location +} + +function Invoke-Build() { + param( + [string]$sdkfolder= "" + ) + $sdkfolder = $sdkfolder -replace "\\", "/" + Push-Location $sdkfolder + dotnet build + if ( !$? ) { + Write-Error "Failed to build sdk. exit code: $?" + Pop-Location + exit 1 + } Pop-Location } @@ -254,6 +315,11 @@ function Invoke-Pack() { $sdkfolder = $sdkfolder -replace "\\", "/" Push-Location $sdkfolder dotnet pack + if ( !$? ) { + Write-Error "Failed to build sdk package. exit code: $?" + Pop-Location + exit 1 + } Pop-Location } function Get-ResourceProviderFromReadme($readmeFile) { diff --git a/eng/scripts/automation/Invoke-DataPlaneGenerateSDKPackage.ps1 b/eng/scripts/automation/Invoke-DataPlaneGenerateSDKPackage.ps1 index 24ebe3394c6a..faf6770567bb 100644 --- a/eng/scripts/automation/Invoke-DataPlaneGenerateSDKPackage.ps1 +++ b/eng/scripts/automation/Invoke-DataPlaneGenerateSDKPackage.ps1 @@ -22,9 +22,16 @@ $outputJson = Get-Content $outputJsonFile | Out-String | ConvertFrom-Json $projectFolder = $outputJson.projectFolder Write-Host "projectFolder:$projectFolder" Remove-Item $outputJsonFile +# Generate Code Invoke-Generate -sdkfolder $projectFolder -if ( $? -ne $True) { - Write-Error "Failed to create generate sdk." +if ( !$? ) { + Write-Error "Failed to generate sdk." + exit 1 +} +# Build +Invoke-Build -sdkfolder $projectFolder +if ( !$? ) { + Write-Error "Failed to build sdk. exit code: $?" exit 1 } # Generate APIs diff --git a/eng/scripts/automation/Invoke-GenerateAndBuild.ps1 b/eng/scripts/automation/Invoke-GenerateAndBuild.ps1 index d06100904018..fec3cf5215d9 100644 --- a/eng/scripts/automation/Invoke-GenerateAndBuild.ps1 +++ b/eng/scripts/automation/Invoke-GenerateAndBuild.ps1 @@ -30,7 +30,7 @@ if ( $serviceType -eq "resource-manager" ) { Write-Host "Data-plane SDK Generation is not implemented currently." exit 1 } -if ( $? -ne $True) { +if ( !$? ) { Write-Error "Failed to create sdk project folder. exit code: $?" exit 1 } @@ -39,12 +39,11 @@ $projectFolder = $newpackageoutputJson.projectFolder $path = $newpackageoutputJson.path Write-Host "projectFolder:$projectFolder" Remove-Item $newpackageoutput - +# Generate Code Invoke-Generate -sdkfolder $projectFolder -if ( $? -ne $True) { - Write-Error "Failed to generate sdk. exit code: $?" - exit 1 -} +# Build +Invoke-Build -sdkfolder $projectFolder + $outputJson = [PSCustomObject]@{ packages = @([pscustomobject]@{packageName="$packageName"; result='succeeded'; path=@("$path");packageFolder="$path"}) } diff --git a/eng/templates/Azure.ServiceTemplate.Template/.template.config/template.json b/eng/templates/Azure.ServiceTemplate.Template/.template.config/template.json deleted file mode 100644 index ede6e919ef98..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/.template.config/template.json +++ /dev/null @@ -1,237 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/template", - "author": "chunyu@microsoft.com", - "classifications": [ "Azure", "ClassLibrary" ], - "identity": "Azure.ServiceTemplate.TemplateProject", - "name": "Azure DataPlane SDK template: client project", - "shortName": "dataplane", - "tags": { - "language": "C#", - "type": "project" - }, - "sourceName": "Azure.ServiceTemplate.Template", - "preferNameDirectory": true, - "guids": [ - "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC", - "FC7B9325-C8EA-4740-AB3B-723EB6549AAD", - "227B2010-BBFC-46F8-84BB-236E9F3A0176", - "3123B983-4452-4B29-8E9A-849867BEC1E6", - "61FB8E18-94E3-4A8F-B6B3-E765F85000F5", - "11EAD7A0-B5E6-4145-B1F1-37A2D9091E07" - ], - "sources": [ - { - "source": "./", - "target": "./", - "modifiers": [ - { - "exclude": [ - "content/**/*" - ] - } - ] - }, - { - "source": "./content", - "target": "../", - "condition": "(includeCI)" - } - ], - "symbols": { - "groupName": { - "type": "parameter", - "datatype":"text", - "isRequired": true, - "description": "The Azure namespace group the service belongs to. e.g. IoT", - "replaces": "GroupName" - }, - "libraryName": { - "type": "parameter", - "datatype":"text", - "isRequired": true, - "description": "The Azure client library name. ie. PurviewAccount. It equals to the client title", - "replaces": "ProviderFullName" - }, - "swagger": { - "type": "parameter", - "datatype":"text", - "isRequired": false, - "defaultValue": "", - "description": "The swagger file link. It can be local file e.g. ./swagger/compute.json or premlink, e.g. https://github.com/dpokluda/azure-rest-api-specs/blob/be397aa65510bd4e8f87da539af2b0025f6f44ca/specification/deviceupdate/data-plane/Microsoft.DeviceUpdate/preview/2020-09-01/deviceupdate.json", - "replaces": "SwaggerFileLink" - }, - "securityScopes": { - "type": "parameter", - "datatype":"text", - "isRequired": false, - "description": "The Azure security scopes. ie. https://api.adu.microsoft.com/.default", - "defaultValue": "", - "replaces": "securityScopes" - }, - "securityHeaderName": { - "type": "parameter", - "datatype":"text", - "isRequired": false, - "description": "The Azure key header name.", - "defaultValue": "", - "replaces": "securityHeaderName" - }, - "tagVersion": { - "type": "parameter", - "datatype":"text", - "isRequired": false, - "description": "The optional parameter specifies the tag in the README.MD. If empty, the default tag in the README.MD is used.", - "defaultValue": "", - "replaces": "SwaggerVersionTag" - }, - "includeCI": { - "type": "parameter", - "datatype": "bool", - "isRequired": false, - "description": "The optional parameter specifies whether generate related pipline ci.yml and test-resources.json in parent folder.", - "defaultValue": "false" - }, - "ServiceName": { - "type": "derived", - "datatype": "text", - "description": "Renames files containing 'Template'", - "valueSource": "libraryName", - "valueTransform": "ServiceShortNameForm", - "fileRename": "Template", - "replaces": "Template" - }, - "ServiceNameLowercase": { - "type": "derived", - "datatype": "text", - "valueSource": "libraryName", - "valueTransform": "ServiceNameLowerForm", - "replaces": "ServiceNameLowercase" - }, - "PackageSafeName": { - "type": "generated", - "generator": "join", - "replaces": "PackageSafeName", - "parameters": { - "symbols": [ - { - "type": "const", - "value": "Azure" - }, - { - "type": "ref", - "value": "groupName" - }, - { - "type": "ref", - "value": "libraryName" - } - ], - "separator": "" - } - }, - "securityTypes": { - "type": "generated", - "generator": "switch", - "replaces": "securityTypes", - "parameters": { - "evaluator": "C++", - "datatype": "string", - "cases": [ - { - "condition": "(securityScopes != \"\" && securityHeaderName != \"\")", - "value": "security:\r\n- AADToken\r\n- AzureKey" - }, - { - "condition": "(securityScopes != \"\" && securityHeaderName == \"\")", - "value": "security: AADToken" - }, - { - "condition": "(securityScopes == \"\" && securityHeaderName != \"\")", - "value": "security: AzureKey" - }, - { - "condition": "(securityScopes == \"\" && securityHeaderName == \"\")", - "value": "" - } - ] - } - }, - "securityScopePrefix": { - "type": "generated", - "generator": "switch", - "replaces": "securityScopePrefix", - "parameters": { - "evaluator": "C++", - "datatype": "string", - "cases": [ - { - "condition": "(securityScopes == \"\")", - "value": "" - }, - { - "condition": "(securityScopes != \"\")", - "value": "security-scopes:" - } - ] - } - }, - "securityHeaderNamePrefix": { - "type": "generated", - "generator": "switch", - "replaces": "securityHeaderNamePrefix", - "parameters": { - "evaluator": "C++", - "datatype": "string", - "cases": [ - { - "condition": "(securityHeaderName == \"\")", - "value": "" - }, - { - "condition": "(securityHeaderName != '')", - "value": "security-header-name:" - } - ] - } - }, - "tagPrefix": { - "type": "generated", - "generator": "switch", - "replaces": "tagPrefix", - "parameters": { - "evaluator": "MSBUILD", - "datatype": "string", - "cases": [ - { - "condition": "('tagVersion' == '')", - "value": "" - }, - { - "condition": "('tagVersion' != '')", - "value": "tag:" - } - ] - } - } - }, - "forms": { - "ServiceShortNameForm": { - "identifier": "replace", - "pattern": "^[mM]icrosoft\\.", - "replacement": "" - }, - "ProviderShortNameLowerForm": { - "identifier": "chain", - "steps": [ - "ProviderShortNameForm", - "lowerCase" - ] - }, - "ServiceNameLowerForm": { - "identifier": "chain", - "steps": [ - "lowerCase" - ] - } - } -} \ No newline at end of file diff --git a/eng/templates/Azure.ServiceTemplate.Template/Azure.ServiceTemplate.Template.sln b/eng/templates/Azure.ServiceTemplate.Template/Azure.ServiceTemplate.Template.sln deleted file mode 100644 index efa41ad281e5..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/Azure.ServiceTemplate.Template.sln +++ /dev/null @@ -1,49 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29709.97 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.TestFramework", "..\..\core\Azure.Core.TestFramework\src\Azure.Core.TestFramework.csproj", "{ECC730C1-4AEA-420C-916A-66B19B79E4DC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.ServiceTemplate.Template", "src\Azure.ServiceTemplate.Template.csproj", "{511762C4-6660-4AA8-9381-125BE87A11CF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.ServiceTemplate.Template.Tests", "tests\Azure.ServiceTemplate.Template.Tests.csproj", "{2DDB6D1B-6AF9-4115-80C0-38C2556FA413B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Release|Any CPU.Build.0 = Release|Any CPU - {8E9A77AC-792A-4432-8320-ACFD46730401}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8E9A77AC-792A-4432-8320-ACFD46730401}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8E9A77AC-792A-4432-8320-ACFD46730401}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8E9A77AC-792A-4432-8320-ACFD46730401}.Release|Any CPU.Build.0 = Release|Any CPU - {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Release|Any CPU.Build.0 = Release|Any CPU - {A4241C1F-A53D-474C-9E4E-075054407E74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4241C1F-A53D-474C-9E4E-075054407E74}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A4241C1F-A53D-474C-9E4E-075054407E74}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A4241C1F-A53D-474C-9E4E-075054407E74}.Release|Any CPU.Build.0 = Release|Any CPU - {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Release|Any CPU.Build.0 = Release|Any CPU - {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A97F4B90-2591-4689-B1F8-5F21FE6D6CAE} - EndGlobalSection -EndGlobal diff --git a/eng/templates/Azure.ServiceTemplate.Template/CHANGELOG.md b/eng/templates/Azure.ServiceTemplate.Template/CHANGELOG.md deleted file mode 100644 index fc03b42f0420..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/CHANGELOG.md +++ /dev/null @@ -1,23 +0,0 @@ -# Release History - -## 1.0.0-beta.1 (Unreleased) - -### Breaking Changes -- Breaking change 1 -- Breaking change 2 -- ... - -### Features Added -- Feature 1 -- Feature 2 -- ... - -### Bugs Fixed -- Bug fix 1 -- Bug fix 2 -- ... - -### Other Changes -- Change 1 -- Change 2 -- ... \ No newline at end of file diff --git a/eng/templates/Azure.ServiceTemplate.Template/samples/README.md b/eng/templates/Azure.ServiceTemplate.Template/samples/README.md deleted file mode 100644 index 982289e315b3..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/samples/README.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -page_type: sample -languages: -- csharp -products: -# Including relevant stubs from https://review.docs.microsoft.com/help/contribute/metadata-taxonomies#product -- azure -name: Azure.ServiceTemplate.Template samples for .NET -description: Samples for the Azure.ServiceTemplate.Template client library. ---- - -# Azure.ServiceTemplate.Template Samples - -- [Creating Resource](https://github.com/Azure/azure-sdk-for-net/blob/3ac301ac6435c818ad7a9946ab1c4023cee236ff/eng/templates/Azure.ServiceTemplate.Template/samples/Sample1_CreateResource.md) \ No newline at end of file diff --git a/eng/templates/Azure.ServiceTemplate.Template/samples/Sample1_CreateResource.md b/eng/templates/Azure.ServiceTemplate.Template/samples/Sample1_CreateResource.md deleted file mode 100644 index c1dd2bd225a0..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/samples/Sample1_CreateResource.md +++ /dev/null @@ -1,46 +0,0 @@ -# Sample readme template - -Use the guidelines in each section of this template to write samples, for an example following this template. - -This sample shows how to detect all the anomalies in the entire time series. - -To get started, make sure you have satisfied all the prerequisites and got all the resources required by [README][README]. - -**write the sample code snippets as following example** - -## Detect anomalies of the entire series - -Call the client's `DetectEntireSeriesAsync` method with the `DetectRequest` object and await the response as an `EntireDetectResponse` object. Iterate through the response's `IsAnomaly` values and print any that are true. These values correspond to the index of anomalous data points, if any were found. - -```C# Snippet:DetectEntireSeriesAnomaly -//detect -Console.WriteLine("Detecting anomalies in the entire time series."); - -EntireDetectResponse result = await client.DetectEntireSeriesAsync(request).ConfigureAwait(false); - -if (result.IsAnomaly.Contains(true)) -{ - Console.WriteLine("An anomaly was detected at index:"); - for (int i = 0; i < request.Series.Count; ++i) - { - if (result.IsAnomaly[i]) - { - Console.Write(i); - Console.Write(" "); - } - } - Console.WriteLine(); -} -else -{ - Console.WriteLine(" No anomalies detected in the series."); -} -``` - -// **list the links to the full example source files as following**\ -To see the full example source files, see: - -* [Detect Entire Series Anomaly](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/anomalydetector/Azure.AI.AnomalyDetector/tests/samples/Sample1_DetectEntireSeriesAnomaly.cs) - -[README]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/anomalydetector/Azure.AI.AnomalyDetector/README.md -[SampleData]: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/anomalydetector/Azure.AI.AnomalyDetector/tests/samples/data/request-data.csv diff --git a/eng/templates/Azure.ServiceTemplate.Template/src/Azure.ServiceTemplate.Template.csproj b/eng/templates/Azure.ServiceTemplate.Template/src/Azure.ServiceTemplate.Template.csproj deleted file mode 100644 index febf05b36761..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/src/Azure.ServiceTemplate.Template.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - This is the Template client library for developing .NET applications with rich experience. - Azure SDK Code Generation Template for Azure Data Plane - 1.0.0-beta.1 - Azure Template - $(RequiredTargetFrameworks) - $(NoWarn);419;AZC0012 - true - $(DefineConstants);EXPERIMENTAL - true - - - - - - - - - - - - \ No newline at end of file diff --git a/eng/templates/Azure.ServiceTemplate.Template/tests/Azure.ServiceTemplate.Template.Tests.csproj b/eng/templates/Azure.ServiceTemplate.Template/tests/Azure.ServiceTemplate.Template.Tests.csproj deleted file mode 100644 index 514cd95aab9d..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/tests/Azure.ServiceTemplate.Template.Tests.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - $(RequiredTargetFrameworks) - - - $(NoWarn);CS1591 - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/eng/templates/Azure.ServiceTemplate.Template/tests/Samples/Sample1_CreateResource.cs b/eng/templates/Azure.ServiceTemplate.Template/tests/Samples/Sample1_CreateResource.cs deleted file mode 100644 index 7074120d4434..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/tests/Samples/Sample1_CreateResource.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Linq; -using System.Text.Json; -using System.Threading.Tasks; -using Azure.Core; -using Azure.Core.TestFramework; -using NUnit.Framework; - -namespace Azure.ServiceTemplate.Template.Tests.Samples -{ - public partial class TemplateSamples : SamplesBase - { - // Get service Client. - // public TemplateServiceClient GetClient() - // { - // var endpoint = TestEnvironment.Endpoint; - - // #region Snippet:TemplateServiceAuthenticate - // var serviceClient = new TemplateServiceClient(new Uri(endpoint), new DefaultAzureCredential()); - // #endregion - - // return serviceClient; - // } - - // [Test] -- Enable the tests when you're running the samples for the service - // [Test] - // public async Task CreateResource() - // { - // #region Snippet:CreateResource - - // var client = GetClient(); - // var resource = new - // { - // name = "TemplateResource", - // id = "123", - // }; - // Response response = await client.CreateAsync(RequestContent.Create(resource)); - // using JsonDocument resourceJson = JsonDocument.Parse(response.Content.ToMemory()); - // string resourceName = resourceJson.RootElement.GetProperty("name").ToString(); - // string resourceId = resourceJson.RootElement.GetProperty("id").ToString(); - // Console.WriteLine($"Name: {resourceName} \n Id: {resourceId}."); - - // #endregion - // } - } -} diff --git a/eng/templates/Azure.ServiceTemplate.Template/tests/TemplateClientTest.cs b/eng/templates/Azure.ServiceTemplate.Template/tests/TemplateClientTest.cs deleted file mode 100644 index 4d5e1991a2a3..000000000000 --- a/eng/templates/Azure.ServiceTemplate.Template/tests/TemplateClientTest.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.IO; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; -using Azure.Core.Pipeline; -using Azure.Core.TestFramework; -using NUnit.Framework; - -namespace Azure.ServiceTemplate.Template.Tests -{ - public class TemplateClientTest: RecordedTestBase - { - public TemplateClientTest(bool isAsync) : base(isAsync) - { - } - - /* Greate the client and instrument it as following. */ - // private TemplateClient CreateClient() - // { - // var httpHandler = new HttpClientHandler(); - // httpHandler.ServerCertificateCustomValidationCallback = (_, _, _, _) => - // { - // return true; - // }; - // var options = new TemplateClientOptions { Transport = new HttpClientTransport(httpHandler) }; - // var client = InstrumentClient( - // new TemplateClient(TestEnvironment.Endpoint, TestEnvironment., TestEnvironment.Credential, InstrumentClientOptions(options))); - // return client; - // } - // Add Test here as following. - // [RecordedTest] - // public async Task TestOperation() - // { - // } - - [RecordedTest] - public void TestOperation() - { - Assert.IsTrue(true); - } - - // Add live tests here. If you need more information please refer https://github.com/Azure/azure-sdk-for-net/blob/main/CONTRIBUTING.md#live-testing and - // here are some examples: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/synapse/Azure.Analytics.Synapse.AccessControl/tests/AccessControlClientLiveTests.cs. - - #region Helpers - - private static BinaryData GetContentFromResponse(Response r) - { - // Workaround azure/azure-sdk-for-net#21048, which prevents .Content from working when dealing with responses - // from the playback system. - - MemoryStream ms = new MemoryStream(); - r.ContentStream.CopyTo(ms); - return new BinaryData(ms.ToArray()); - } - #endregion - } -} diff --git a/eng/templates/Azure.ServiceTemplate.Template/api/Azure.ServiceTemplate.Template.netstandard2.0.cs b/sdk/template/.content/api/Azure.Template.netstandard2.0.cs similarity index 54% rename from eng/templates/Azure.ServiceTemplate.Template/api/Azure.ServiceTemplate.Template.netstandard2.0.cs rename to sdk/template/.content/api/Azure.Template.netstandard2.0.cs index 3f1fde997248..4ca907af24f2 100644 --- a/eng/templates/Azure.ServiceTemplate.Template/api/Azure.ServiceTemplate.Template.netstandard2.0.cs +++ b/sdk/template/.content/api/Azure.Template.netstandard2.0.cs @@ -1,17 +1,17 @@ -namespace Azure.ServiceTemplate.Template +namespace Azure.Template { public partial class TemplateClient { protected TemplateClient() { } - public TemplateClient(System.Uri endpoint, Azure.Core.TokenCredential credential, Azure.Template.Generated.TemplateServiceClientOptions options = null) { } + public TemplateClient(string endpoint, Azure.Core.TokenCredential credential, Azure.Template.TemplateClientOptions options = null) { } public virtual Azure.Core.Pipeline.HttpPipeline Pipeline { get { throw null; } } } public partial class TemplateClientOptions : Azure.Core.ClientOptions { - public TemplateClientOptions(Azure.Template.Generated.TemplateServiceClientOptions.ServiceVersion version = Azure.Template.Generated.TemplateServiceClientOptions.ServiceVersion.V1_0_0) { } + public TemplateClientOptions(Azure.Template.Generated.TemplateClientOptions.ServiceVersion version = Azure.Template.Generated.TemplateClientOptions.ServiceVersion.V1_0_0) { } public enum ServiceVersion { V1_0_0 = 1, } } -} +} \ No newline at end of file diff --git a/sdk/template/.content/packageResource/CHANGELOG.md b/sdk/template/.content/packageResource/CHANGELOG.md new file mode 100644 index 000000000000..13dd08af78ab --- /dev/null +++ b/sdk/template/.content/packageResource/CHANGELOG.md @@ -0,0 +1,11 @@ +# Release History + +## 1.0.0-beta.1 (Unreleased) + +### Features Added + +### Breaking Changes + +### Bugs Fixed + +### Other Changes diff --git a/eng/templates/Azure.ServiceTemplate.Template/README.md b/sdk/template/.content/packageResource/README.md similarity index 52% rename from eng/templates/Azure.ServiceTemplate.Template/README.md rename to sdk/template/.content/packageResource/README.md index 4b508072b979..8bc0a224e4c7 100644 --- a/eng/templates/Azure.ServiceTemplate.Template/README.md +++ b/sdk/template/.content/packageResource/README.md @@ -1,24 +1,11 @@ -# README.md template - -Use the guidelines in each section of this template to ensure consistency and readability of your README. The README resides in your package's GitHub repository at the root of its directory within the repo. It's also used as the package distribution page (NuGet) and as a Quickstart on docs.microsoft.com. See [Azure.ServiceTemplate.Template/README.md](https://github.com/Azure/azure-sdk-for-net/blob/bb0fbccfc33dd27d1ec6f0870022824d47181e61/sdk/template-dpg/Azure.ServiceTemplate.Template/README.md) for an example following this template. - -**Title**: The H1 of your README should be in the format: `# [Product Name] client library for [Language]` - -* All headings, including the H1, should use **sentence-style capitalization**. Refer to the [Microsoft Style Guide][style-guide-msft] and [Microsoft Cloud Style Guide][style-guide-cloud] for more information. -* Example: `# Azure Batch client library for .NET` - # Azure Template client library for .NET -**Introduction**: The introduction appears directly under the title (H1) of your README. +This section should give out brief introduction of the client library. -* **DO NOT** use an "Introduction" or "Overview" heading (H2) for this section. * First sentence: **Describe the service** briefly. You can usually use the first line of the service's docs landing page for this (Example: [Cosmos DB docs landing page](https://docs.microsoft.com/azure/cosmos-db/)). * Next, add a **bulleted list** of the **most common tasks** supported by the package or library, prefaced with "Use the client library for [Product Name] to:". Then, provide code snippets for these tasks in the [Examples](#examples) section later in the document. Keep the task list short but include those tasks most developers need to perform with your package. -* Include this single line of links targeting your product's content at the bottom of the introduction, making any adjustments as necessary: - - [Source code](https://github.com/Azure/azure-sdk-for-net/tree/bb0fbccfc33dd27d1ec6f0870022824d47181e61/sdk/template-dpg/Azure.ServiceTemplate.Template/src) | [Package (NuGet)](https://www.nuget.org/packages/Azure.AI.AnomalyDetector) | [API reference documentation](https://azure.github.io/azure-sdk-for-net/anomalydetector.html) | [Product documentation](https://docs.microsoft.com/azure/cognitive-services/anomaly-detector/) -> TIP: Your README should be as **brief** as possible but **no more brief** than necessary to get a developer new to Azure, the service, or the package up and running quickly. Keep it brief, but include everything a developer needs to make their first API call successfully. + [Source code](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/src) | [Package (NuGet)](https://www.nuget.org/packages/Azure.Template) | [API reference documentation](https://azure.github.io/azure-sdk-for-net) | [Product documentation](https://docs.microsoft.com/azure) ## Getting started @@ -28,6 +15,12 @@ This section should include everything a developer needs to do to install and cr First, provide instruction for obtaining and installing the package or library. This section might include only a single line of code, like `dotnet add package package-name`, but should enable a developer to successfully install the package from NuGet, npm, or even cloning a GitHub repository. +Install the client library for .NET with [NuGet](https://www.nuget.org/ ): + +```dotnetcli +dotnet add package Azure.Template --prerelease +``` + ### Prerequisites Include a section after the install command that details any requirements that must be satisfied before a developer can [authenticate](#authenticate-the-client) and test all of the snippets in the [Examples](#examples) section. For example, for Cosmos DB: @@ -40,10 +33,6 @@ If your library requires authentication for use, such as for Azure services, inc For example, include details on obtaining an account key and endpoint URI, setting environment variables for each, and initializing the client object. -```C# Snippet:TemplateServiceAuthenticate -var serviceClient = new TemplateServiceClient(new Uri(endpoint), new DefaultAzureCredential()); -``` - ## Key concepts The *Key concepts* section should describe the functionality of the main classes. Point out the most important and useful classes in the package (with links to their reference pages) and explain how those classes work together. Feel free to use bulleted lists, tables, code blocks, or even diagrams for clarity. @@ -51,6 +40,7 @@ The *Key concepts* section should describe the functionality of the main classes Include the *Thread safety* and *Additional concepts* sections below at the end of your *Key concepts* section. You may remove or add links depending on what your library makes use of: ### Thread safety + We guarantee that all client instance methods are thread-safe and independent of each other ([guideline](https://azure.github.io/azure-sdk/dotnet_introduction.html#dotnet-service-methods-thread-safety)). This ensures that the recommendation of reusing client instances is always safe, even across threads. ### Additional concepts @@ -66,73 +56,13 @@ We guarantee that all client instance methods are thread-safe and independent of ## Examples -Include code snippets and short descriptions for each task you listed in the [Introduction](#introduction) (the bulleted list). Briefly explain each operation, but include enough clarity to explain complex or otherwise tricky operations. - -If possible, use the same example snippets that your in-code documentation uses. For example, use the snippets in your `samples`. The `sample` file containing the snippets should reside alongside your package's code, and should be tested in an automated fashion. Please refer [this](https://github.com/Azure/azure-sdk-for-net/blob/main/CONTRIBUTING.md#updating-sample-snippets) doc to know more about snippets. - -Each example in the *Examples* section starts with an H3 that describes the example. At the top of this section, just under the *Examples* H2, add a bulleted list linking to each example H3. Each example should deep-link to the types and/or members used in the example. - -* [Create resource](#create-resource) -* [Get resource](#get-resource) -* [List resources](#list-resources) -* [Delete resource](#delete-resource) - -### Create resource - -Use the `Create` method to create a resource. - -```C# Snippet:CreateResource -var client = GetClient(); -var resource = new -{ - name = "TemplateResource", - id = "123", -}; -Response response = await client.CreateAsync(RequestContent.Create(resource)); -using JsonDocument resourceJson = JsonDocument.Parse(response.Content.ToMemory()); -string resourceName = resourceJson.RootElement.GetProperty("name").ToString(); -string resourceId = resourceJson.RootElement.GetProperty("id").ToString(); -Console.WriteLine($"Name: {resourceName} \n Id: {resourceId}."); -``` - -### Get resource - -The `Get` method retrieves a data from the service. The `id` parameter is the unique ID of the resource. - -```C# Snippet:RetrieveResource -var client = GetClient(); -var response = await client.GetResourceAsync("123"); -using JsonDocument resourceJson = JsonDocument.Parse(response.Content.ToMemory()); -string resourceName = resourceJson.RootElement.GetProperty("name").ToString(); -string resourceId = resourceJson.RootElement.GetProperty("id").ToString(); -Console.WriteLine($"Name: {resourceName} \n Id: {resourceId}."); -``` - -### List resources - -The `GetResources` method retrieves the list of resources from the service. - -```C# Snippet:ListResources -var client = GetClient(); -AsyncPageable pageable = client.GetResourcesAsync(); -await foreach (var page in pageable.AsPages()) -{ - foreach (var resourceBinaryData in page.Values) - { - using JsonDocument resourceJson = JsonDocument.Parse(resourceBinaryData.ToMemory()); - Console.WriteLine(resourceJson.RootElement.GetProperty("name").ToString()); - Console.WriteLine(resourceJson.RootElement.GetProperty("id").ToString()); - } -} -``` +You can familiarize yourself with different APIs using [Samples](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/template/Azure.Template/samples). -### Delete resource +### -The `Delete` method deletes the resource from the service. +You can create a client and call the client's `` method. -```C# Snippet:DeleteResource -var client = GetClient(); -await client.DeleteAsync("123"); +```C# Snippet:Azure_Template_Scenario ``` ## Troubleshooting @@ -157,4 +87,4 @@ This is a template, but your SDK readme should include details on how to contrib [style-guide-msft]: https://docs.microsoft.com/style-guide/capitalization [style-guide-cloud]: https://aka.ms/azsdk/cloud-style-guide -![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net%2Fsdk%2Ftemplate%2FAzure.Template%2FREADME.png) +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net/sdk/template/Azure.Template/README.png) \ No newline at end of file diff --git a/sdk/template/.content/perf/Program.cs b/sdk/template/.content/perf/Program.cs new file mode 100644 index 000000000000..78a52ddce190 --- /dev/null +++ b/sdk/template/.content/perf/Program.cs @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Reflection; +using Azure.Test.Perf; + + await PerfProgram.Main(Assembly.GetEntryAssembly(), args); diff --git a/sdk/template/.content/perf/TemplateClientTest.cs b/sdk/template/.content/perf/TemplateClientTest.cs new file mode 100644 index 000000000000..c6a5eb8b4475 --- /dev/null +++ b/sdk/template/.content/perf/TemplateClientTest.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Azure.Identity; +using Azure.Test.Perf; +using CommandLine; + +namespace Azure.Template.Perf +{ + public class TemplateClientTest : PerfTest + { + /* please refer to PerfSampleLink to write perf test. */ + + public TemplateClientTest(TemplateClientPerfOptions options) : base(options) + { + } + public class TemplateClientPerfOptions : PerfOptions + { + } + + public override void Run(CancellationToken cancellationToken) + { + } + + public override async Task RunAsync(CancellationToken cancellationToken) + { + await Task.Run(() => + { + Console.WriteLine("exec some async operation"); + }); + } + } +} diff --git a/sdk/template/.content/samples/README.md b/sdk/template/.content/samples/README.md new file mode 100644 index 000000000000..ec5edcbf0252 --- /dev/null +++ b/sdk/template/.content/samples/README.md @@ -0,0 +1,14 @@ +--- +page_type: sample +languages: +- csharp +products: +# Including relevant stubs from https://review.docs.microsoft.com/help/contribute/metadata-taxonomies#product +- azure +name: Azure.Template samples for .NET +description: Samples for the Azure.Template client library. +--- + +# Azure.Template Samples + + diff --git a/sdk/template/.content/samples/Sample1_HelloWorld.md b/sdk/template/.content/samples/Sample1_HelloWorld.md new file mode 100644 index 000000000000..84637e9c2779 --- /dev/null +++ b/sdk/template/.content/samples/Sample1_HelloWorld.md @@ -0,0 +1,15 @@ +# + +To use these samples, you'll first need to set up resources. See [getting started](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/README.md#getting-started) for details. + +## + +You can create a client and call the client's `` method + +```C# Snippet:Azure_Template_Scenario +``` + +To see the full example source files, see: +* [HelloWorld](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorld.cs)) + + \ No newline at end of file diff --git a/sdk/template/.content/samples/Sample1_HelloWorldAsync.md b/sdk/template/.content/samples/Sample1_HelloWorldAsync.md new file mode 100644 index 000000000000..0bb00e0cad10 --- /dev/null +++ b/sdk/template/.content/samples/Sample1_HelloWorldAsync.md @@ -0,0 +1,15 @@ +# + +To use these samples, you'll first need to set up resources. See [getting started](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/README.md#getting-started) for details. + +## asynchronously + +You can create a client and call the client's `` method + +```C# Snippet:Azure_Template_ScenarioAsync +``` + +To see the full example source files, see: +* [HelloWorld](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorldAsync.cs)) + + \ No newline at end of file diff --git a/eng/templates/Azure.ServiceTemplate.Template/src/GlobalSuppressions.cs b/sdk/template/.content/src/GlobalSuppressions.cs similarity index 100% rename from eng/templates/Azure.ServiceTemplate.Template/src/GlobalSuppressions.cs rename to sdk/template/.content/src/GlobalSuppressions.cs diff --git a/eng/templates/Azure.ServiceTemplate.Template/src/autorest.md b/sdk/template/.content/src/autorest.md similarity index 57% rename from eng/templates/Azure.ServiceTemplate.Template/src/autorest.md rename to sdk/template/.content/src/autorest.md index dfa4977b9591..9c63f4faee1b 100644 --- a/eng/templates/Azure.ServiceTemplate.Template/src/autorest.md +++ b/sdk/template/.content/src/autorest.md @@ -7,10 +7,8 @@ Run `dotnet build /t:GenerateCode` to generate code. ``` yaml input-file: SwaggerFileLink -namespace: Azure.ServiceTemplate.Template -public-clients: true -data-plane: true +namespace: Azure.Template securityTypes -securityScopePrefix securityScopes -securityHeaderNamePrefix securityHeaderName +securityScopePrefix: securityScopes +securityHeaderNamePrefix: securityHeaderName ``` diff --git a/eng/templates/Azure.ServiceTemplate.Template/src/properties/AssemblyInfo.cs b/sdk/template/.content/src/properties/AssemblyInfo.cs similarity index 100% rename from eng/templates/Azure.ServiceTemplate.Template/src/properties/AssemblyInfo.cs rename to sdk/template/.content/src/properties/AssemblyInfo.cs diff --git a/sdk/template/.content/stress/Program.cs b/sdk/template/.content/stress/Program.cs new file mode 100644 index 000000000000..5bb749f30cf1 --- /dev/null +++ b/sdk/template/.content/stress/Program.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Azure.Test.Stress; + +namespace Azure.Template.Stress +{ + public class Program + { + public static async Task Main(string[] args) + { + await StressProgram.Main(typeof(Program).Assembly, args); + } + } +} diff --git a/sdk/template/.content/stress/TemplateClientTest.cs b/sdk/template/.content/stress/TemplateClientTest.cs new file mode 100644 index 000000000000..901856b06515 --- /dev/null +++ b/sdk/template/.content/stress/TemplateClientTest.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Azure.Identity; +using Azure.Test.Stress; +using CommandLine; + +namespace Azure.Template.Stress +{ + public class TemplateClientTest : StressTest + { + public TemplateClientTest(TemplateClientStressOptions options, TemplateClientStressMetrics metrics) : base(options, metrics) + { + } + + /* please refer to StressSampleLink to write stress tests. */ + + public override async Task RunAsync(CancellationToken cancellationToken) + { + await Task.Run(() => + { + Console.WriteLine("exec some async operation"); + }); + } + public class TemplateClientStressMetrics : StressMetrics + { + } + + public class TemplateClientStressOptions : StressOptions + { + } + } +} diff --git a/eng/templates/Azure.ServiceTemplate.Template/content/ci.yml b/sdk/template/.content/testResource/ci.yml similarity index 70% rename from eng/templates/Azure.ServiceTemplate.Template/content/ci.yml rename to sdk/template/.content/testResource/ci.yml index e7481c865252..39167577452f 100644 --- a/eng/templates/Azure.ServiceTemplate.Template/content/ci.yml +++ b/sdk/template/.content/testResource/ci.yml @@ -8,7 +8,7 @@ trigger: - release/* paths: include: - - sdk/ServiceNameLowercase/ + - sdk/template/ pr: branches: @@ -19,13 +19,13 @@ pr: - release/* paths: include: - - sdk/ServiceNameLowercase/ + - sdk/template/ extends: template: /eng/pipelines/templates/stages/archetype-sdk-client.yml parameters: - ServiceDirectory: ServiceNameLowercase + ServiceDirectory: template ArtifactName: packages Artifacts: - - name: Azure.ServiceTemplate.Template - safeName: PackageSafeName + - name: Azure.Template + safeName: AzureTemplate diff --git a/sdk/template/.content/testResource/test-resources.json b/sdk/template/.content/testResource/test-resources.json new file mode 100644 index 000000000000..b28ae70a77a0 --- /dev/null +++ b/sdk/template/.content/testResource/test-resources.json @@ -0,0 +1,85 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "baseName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "The base resource name." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "72f988bf-86f1-41af-91ab-2d7cd011db47", + "metadata": { + "description": "The tenant ID to which the application and resources belong." + } + }, + "testApplicationOid": { + "type": "string", + "defaultValue": "b3653439-8136-4cd5-aac3-2a9460871ca6", + "metadata": { + "description": "The client OID to grant access to test resources." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "The location of the resource. By default, this is the same as the resource group." + } + } + }, + "variables": { + "secretValue": "Very secret value" + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2016-10-01", + "name": "[parameters('baseName')]", + "location": "[parameters('location')]", + "properties": { + "sku": { + "family": "A", + "name": "premium" + }, + "tenantId": "[parameters('tenantId')]", + "accessPolicies": [ + { + "tenantId": "[parameters('tenantId')]", + "objectId": "[parameters('testApplicationOid')]", + "permissions": { + "secrets": [ + "get" + ] + } + } + ] + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "name": "[concat(parameters('baseName'), '/TestSecret')]", + "apiVersion": "2016-10-01", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', parameters('baseName'))]" + ], + "properties": { + "value": "[variables('secretValue')]" + } + } + ], + "outputs": { + "KEYVAULT_URL": { + "type": "string", + "value": "[reference(parameters('baseName')).vaultUri]" + }, + "KEYVAULT_SECRET": { + "type": "string", + "value": "[variables('secretValue')]" + } + } +} diff --git a/eng/templates/Azure.ServiceTemplate.Template/content/tests.yml b/sdk/template/.content/testResource/tests.yml similarity index 75% rename from eng/templates/Azure.ServiceTemplate.Template/content/tests.yml rename to sdk/template/.content/testResource/tests.yml index 7f4825e231c9..6c539b353599 100644 --- a/eng/templates/Azure.ServiceTemplate.Template/content/tests.yml +++ b/sdk/template/.content/testResource/tests.yml @@ -3,5 +3,5 @@ trigger: none extends: template: /eng/pipelines/templates/stages/archetype-sdk-tests.yml parameters: - ServiceDirectory: ServiceNameLowercase + ServiceDirectory: template SupportedClouds: 'Public' diff --git a/sdk/template/.content/tests/Samples/Sample1_HelloWorld.cs b/sdk/template/.content/tests/Samples/Sample1_HelloWorld.cs new file mode 100644 index 000000000000..ee3cbeed0a46 --- /dev/null +++ b/sdk/template/.content/tests/Samples/Sample1_HelloWorld.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.TestFramework; +using NUnit.Framework; + +namespace Azure.Template.Tests.Samples +{ + public partial class TemplateSamples: SamplesBase + { + /* please refer to SamplesLink to write samples. */ + #region Snippet:Azure_Template_Scenario + + #endregion + } +} diff --git a/sdk/template/.content/tests/Samples/Sample1_HelloWorldAsync.cs b/sdk/template/.content/tests/Samples/Sample1_HelloWorldAsync.cs new file mode 100644 index 000000000000..7bd159a68548 --- /dev/null +++ b/sdk/template/.content/tests/Samples/Sample1_HelloWorldAsync.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.TestFramework; +using NUnit.Framework; + +namespace Azure.Template.Tests.Samples +{ + public partial class TemplateSamples: SamplesBase + { + /* please refer to AsyncSamplesLink to write samples. */ + #region Snippet:Azure_Template_ScenarioAsync + + #endregion + } +} diff --git a/sdk/template/.content/tests/TemplateClientTest.cs b/sdk/template/.content/tests/TemplateClientTest.cs new file mode 100644 index 000000000000..4d3ecd45ada3 --- /dev/null +++ b/sdk/template/.content/tests/TemplateClientTest.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.IO; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; +using Azure.Core.Pipeline; +using Azure.Core.TestFramework; +using NUnit.Framework; + +namespace Azure.Template.Tests +{ + public class TemplateClientTest: RecordedTestBase + { + public TemplateClientTest(bool isAsync) : base(isAsync) + { + } + + /* please refer to TestSampleLink to write tests. */ + + [RecordedTest] + public void TestOperation() + { + Assert.IsTrue(true); + } + + #region Helpers + + private static BinaryData GetContentFromResponse(Response r) + { + // Workaround azure/azure-sdk-for-net#21048, which prevents .Content from working when dealing with responses + // from the playback system. + + MemoryStream ms = new MemoryStream(); + r.ContentStream.CopyTo(ms); + return new BinaryData(ms.ToArray()); + } + #endregion + } +} diff --git a/eng/templates/Azure.ServiceTemplate.Template/tests/TemplateClientTestEnvironment.cs b/sdk/template/.content/tests/TemplateClientTestEnvironment.cs similarity index 87% rename from eng/templates/Azure.ServiceTemplate.Template/tests/TemplateClientTestEnvironment.cs rename to sdk/template/.content/tests/TemplateClientTestEnvironment.cs index f174a7e6c56a..d15bbad68e21 100644 --- a/eng/templates/Azure.ServiceTemplate.Template/tests/TemplateClientTestEnvironment.cs +++ b/sdk/template/.content/tests/TemplateClientTestEnvironment.cs @@ -3,7 +3,7 @@ using Azure.Core.TestFramework; -namespace Azure.ServiceTemplate.Template.Tests +namespace Azure.Template.Tests { public class TemplateClientTestEnvironment : TestEnvironment { diff --git a/sdk/template/.template.config/template.json b/sdk/template/.template.config/template.json index ff757bc710fa..cacecf7b171a 100644 --- a/sdk/template/.template.config/template.json +++ b/sdk/template/.template.config/template.json @@ -1,93 +1,466 @@ { - "$schema": "http://json.schemastore.org/template", - "author": "Azure SDK for .NET", - "description": "Create a new Azure SDK e.g. dotnet new azuresdk --name Azure.MyService --output sdk/myservice --ServiceDirectory myservice --ProjectName Azure.MyService", - "classifications": [ "Azure", "ClassLibrary" ], - "identity": "Azure.Template", - "name": "Azure SDK", - "shortName": "azuresdk", - "tags": { - "language": "C#", - "type": "project" - }, - "sourceName": "Azure.Template", - "preferNameDirectory": true, - "symbols": { - "ServiceDirectory": { - "type": "parameter", - "description": "This must match the name of the directory you create under the \"sdk\" directory e.g., \"myservice\" if outputting \"sdk/mysevice\".", - "datatype": "text", - "isRequired": true - }, - "ProjectName": { - "type": "parameter", - "description": "This must match the name of the project e.g. pass the same value as you do to the built-in \"--name\" parameter.", - "datatype": "text", - "isRequired": true - }, - "ProjectNameUnderscored": { - "type": "generated", - "generator": "regex", - "parameters": { - "source": "ProjectName", - "steps": [ - { - "regex": "\\.", - "replacement": "_" - } - ] - }, - "replaces": "Azure_Template" - }, - "ServiceDirectoryPath": { - "type": "generated", - "generator": "join", - "parameters": { - "symbols": [ - { - "type": "const", - "value": "sdk/" - }, - { - "type": "ref", - "value": "ServiceDirectory" - } - ], - "separator": "" - }, - "replaces": "sdk/template" - }, - "SafeProjectName": { - "type": "generated", - "generator": "regex", - "parameters": { - "source": "ProjectName", - "steps": [ - { - "regex": "\\.", - "replacement": "" - } - ] - }, - "replaces": "AzureTemplate" - }, - "YamlServiceDirectory": { - "type": "generated", - "generator": "join", - "parameters": { - "symbols": [ - { - "type": "const", - "value": "ServiceDirectory: " - }, - { - "type": "ref", - "value": "ServiceDirectory" - } - ], - "separator": "" - }, - "replaces": "ServiceDirectory: template" + "$schema": "http://json.schemastore.org/template", + "classifications": [ "Azure", "ClassLibrary" ], + "identity": "Azure.Template", + "name": "Azure DataPlane SDK template: client project", + "shortName": "azsdkdpg", + "tags": { + "language": "C#", + "type": "project" + }, + "sourceName": "Azure.Template", + "preferNameDirectory": false, + "guids": [ + "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC", + "FC7B9325-C8EA-4740-AB3B-723EB6549AAD", + "227B2010-BBFC-46F8-84BB-236E9F3A0176", + "3123B983-4452-4B29-8E9A-849867BEC1E6", + "61FB8E18-94E3-4A8F-B6B3-E765F85000F5", + "11EAD7A0-B5E6-4145-B1F1-37A2D9091E07" + ], + "sources": [ + { + "source": "./Azure.Template", + "target": "./Azure.Template", + "modifiers": [ + { + "exclude": [ + "api/**/*", + "samples/**/*.md", + "tests/**/*.cs", + "perf/**/*.cs", + "stress/**/*.cs", + "src/**/*.cs", + "src/**/*.md", + "src/swagger/**/*", + "tests/SessionRecords/**/*", + ".vs/**/*" + ] + } + ] + }, + { + "source": "./.content", + "target": "./Azure.Template", + "modifiers": [ + { + "exclude": [ + "testResource/**/*", + "packageResource/**/*" + ] } + ] + }, + { + "source": "./.content/testResource", + "target": "./", + "condition": "(includeCI)" + }, + { + "source": "./.content/packageResource", + "target": "./Azure.Template/" + } + ], + "symbols": { + "serviceDirectory": { + "type": "parameter", + "datatype":"text", + "isRequired": true, + "description": "The Azure client serviceDirectory name. ie. purview. It equals to the name of the directory in the specification folder of the azure-rest-api-specs repo that contains the REST API definition file." + }, + "groupName": { + "type": "parameter", + "datatype":"text", + "isRequired": true, + "description": "The Azure namespace group the service belongs to. e.g. IoT", + "replaces": "GroupName" + }, + "clientName": { + "type": "parameter", + "datatype":"text", + "isRequired": true, + "description": "The Azure client library name. ie. PurviewAccount. It equals to the client title", + "replaces": "ProviderFullName" + }, + "swagger": { + "type": "parameter", + "datatype":"text", + "isRequired": true, + "description": "The swagger file link. It can be local file e.g. ./swagger/compute.json or premlink, e.g. https://github.com/dpokluda/azure-rest-api-specs/blob/be397aa65510bd4e8f87da539af2b0025f6f44ca/specification/deviceupdate/data-plane/Microsoft.DeviceUpdate/preview/2020-09-01/deviceupdate.json", + "replaces": "SwaggerFileLink" + }, + "securityScopes": { + "type": "parameter", + "datatype":"text", + "isRequired": false, + "description": "The Azure security scopes. ie. https://api.adu.microsoft.com/.default", + "defaultValue": "", + "replaces": "securityScopes" + }, + "securityHeaderName": { + "type": "parameter", + "datatype":"text", + "isRequired": false, + "description": "The Azure key header name.", + "defaultValue": "", + "replaces": "securityHeaderName" + }, + "tagVersion": { + "type": "parameter", + "datatype":"text", + "isRequired": false, + "description": "The optional parameter specifies the tag in the README.MD. If empty, the default tag in the README.MD is used.", + "defaultValue": "", + "replaces": "SwaggerVersionTag" + }, + "includeCI": { + "type": "parameter", + "datatype": "bool", + "isRequired": false, + "description": "The optional parameter specifies whether generate related pipline ci.yml and test-resources.json in parent folder.", + "defaultValue": "true" + }, + "perfSampleLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/perf/TemplateClientTest.cs", + "replaces": "PerfSampleLink" + }, + "stressSampleLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/stress/TemplateClientTest.cs", + "replaces": "StressSampleLink" + }, + "testSampleLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/TemplateClientLiveTests.cs", + "replaces": "TestSampleLink" + }, + "samplesLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1.HelloWorld.cs", + "replaces": "SamplesLink" + }, + "asyncSamplesLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1.HelloWorldAsync.cs", + "replaces": "AsyncSamplesLink" + }, + "readmeLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/samples/README.md", + "replaces": "ReadmeLink" + }, + "sampleReadmeLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/main/sdk/template/Azure.Template/samples/Sample1_HelloWorld.md", + "replaces": "SampleReadmeLink" + }, + "asyncSampleReadmeLink": { + "type": "parameter", + "datatype": "text", + "isRequired": false, + "defaultValue": "https://github.com/Azure/azure-sdk-for-net/main/sdk/template/Azure.Template/samples/Sample1_HelloWorldAsync.md", + "replaces": "AsyncSampleReadmeLink" + }, + "ClientNameCapitalCase": { + "type": "derived", + "datatype": "text", + "valueSource": "ClientName", + "valueTransform": "firstUpperCase", + "replaces": "Template" + }, + "ClientNameWithSuffix": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "ref", + "value": "ClientNameCapitalCase" + }, + { + "type": "const", + "value": "Client" + } + ], + "separator": "" + }, + "description": "Renames files containing 'TemplateClient'", + "valueSource": "Cl", + "valueTransform": "ServiceShortNameForm", + "fileRename": "TemplateClient", + "replaces": "TemplateClient" + }, + "ServiceNameLowercase": { + "type": "derived", + "datatype": "text", + "valueSource": "serviceDirectory", + "valueTransform": "ServiceNameLowerForm" + }, + "ServiceNameCapitalCase": { + "type": "derived", + "datatype": "text", + "valueSource": "serviceDirectory", + "valueTransform": "firstUpperCase" + }, + "ServiceDirectoryPath": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "const", + "value": "sdk/" + }, + { + "type": "ref", + "value": "ServiceNameLowercase" + } + ], + "separator": "" + }, + "replaces": "sdk/template" + }, + "PackageName": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "const", + "value": "Azure" + }, + { + "type": "ref", + "value": "groupName" + }, + { + "type": "ref", + "value": "ClientNameCapitalCase" + } + ], + "separator": "." + }, + "replaces": "Azure.Template" + }, + "PackageSafeName": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "const", + "value": "Azure" + }, + { + "type": "ref", + "value": "groupName" + }, + { + "type": "ref", + "value": "ClientNameCapitalCase" + } + ], + "separator": "" + }, + "replaces": "AzureTemplate" + }, + "PackageNameUnderscored": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "const", + "value": "Azure" + }, + { + "type": "ref", + "value": "groupName" + }, + { + "type": "ref", + "value": "ClientName" + } + ], + "separator": "_" + }, + "replaces": "Azure_Template" + }, + "projectFileName": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "ref", + "value": "PackageName" + }, + { + "type": "const", + "value": "." + } + ], + "separator": "" + }, + "fileRename": "Azure.Template." + }, + "YamlServiceDirectory": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "const", + "value": "ServiceDirectory: " + }, + { + "type": "ref", + "value": "ServiceNameLowercase" + } + ], + "separator": "" + }, + "replaces": "ServiceDirectory: template" + }, + "AzureResourceProviderNamespace": { + "type": "generated", + "generator": "join", + "parameters": { + "symbols": [ + { + "type": "const", + "value": "Microsoft" + }, + { + "type": "ref", + "value": "ServiceNameCapitalCase" + } + ], + "separator": "." + }, + "replaces": "Microsoft.Template" + }, + "securityTypes": { + "type": "generated", + "generator": "switch", + "replaces": "securityTypes", + "parameters": { + "evaluator": "C++", + "datatype": "string", + "cases": [ + { + "condition": "(securityScopes != \"\" && securityHeaderName != \"\")", + "value": "security:\r\n- AADToken\r\n- AzureKey" + }, + { + "condition": "(securityScopes != \"\" && securityHeaderName == \"\")", + "value": "security: AADToken" + }, + { + "condition": "(securityScopes == \"\" && securityHeaderName != \"\")", + "value": "security: AzureKey" + }, + { + "condition": "(securityScopes == \"\" && securityHeaderName == \"\")", + "value": "" + } + ] + } + }, + "securityScopePrefix": { + "type": "generated", + "generator": "switch", + "replaces": "securityScopePrefix:", + "parameters": { + "evaluator": "C++", + "datatype": "string", + "cases": [ + { + "condition": "(securityScopes == \"\")", + "value": "" + }, + { + "condition": "(securityScopes != \"\")", + "value": "security-scopes:" + } + ] + } + }, + "securityHeaderNamePrefix": { + "type": "generated", + "generator": "switch", + "replaces": "securityHeaderNamePrefix:", + "parameters": { + "evaluator": "C++", + "datatype": "string", + "cases": [ + { + "condition": "(securityHeaderName == \"\")", + "value": "" + }, + { + "condition": "(securityHeaderName != '')", + "value": "security-header-name:" + } + ] + } + }, + "tagPrefix": { + "type": "generated", + "generator": "switch", + "replaces": "tagPrefix", + "parameters": { + "evaluator": "MSBUILD", + "datatype": "string", + "cases": [ + { + "condition": "('tagVersion' == '')", + "value": "" + }, + { + "condition": "('tagVersion' != '')", + "value": "tag:" + } + ] + } + } + }, + "forms": { + "firstUpperCase": { + "identifier": "firstUpperCase" + }, + "ServiceShortNameForm": { + "identifier": "replace", + "pattern": "^[mM]icrosoft\\.", + "replacement": "" + }, + "ProviderShortNameLowerForm": { + "identifier": "chain", + "steps": [ + "ProviderShortNameForm", + "lowerCase" + ] + }, + "ServiceNameLowerForm": { + "identifier": "chain", + "steps": [ + "lowerCase" + ] } -} + } +} \ No newline at end of file diff --git a/sdk/template/Azure.Template/Azure.Template.sln b/sdk/template/Azure.Template/Azure.Template.sln index 14956ba4f59b..28836bc9a0f8 100644 --- a/sdk/template/Azure.Template/Azure.Template.sln +++ b/sdk/template/Azure.Template/Azure.Template.sln @@ -3,19 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29709.97 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template", "src\Azure.Template.csproj", "{E33D09D9-D809-472C-82E6-6A26BDB86FC2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.TestFramework", "..\..\core\Azure.Core.TestFramework\src\Azure.Core.TestFramework.csproj", "{ECC730C1-4AEA-420C-916A-66B19B79E4DC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template.Tests", "tests\Azure.Template.Tests.csproj", "{4F476D56-DDE7-43D3-8CB4-BA1E77F5A300}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Template", "src\Azure.Template.csproj", "{28FF4005-4467-4E36-92E7-DEA27DEB1519}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.TestFramework", "..\..\core\Azure.Core.TestFramework\src\Azure.Core.TestFramework.csproj", "{8052009B-2126-44A3-88CD-4F3B17894C64}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Template.Perf", "perf\Azure.Template.Perf.csproj", "{30C5FF85-655A-49FC-A324-16438130FF3F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template.Stress", "stress\Azure.Template.Stress.csproj", "{9CB28A07-1056-4FD8-BB26-A091AD95C08B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Template.Tests", "tests\Azure.Template.Tests.csproj", "{1F1CD1D4-9932-4B73-99D8-C252A67D4B46}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Test.Stress", "..\..\..\common\Stress\Azure.Test.Stress\Azure.Test.Stress.csproj", "{0B991CA1-E570-4292-BABF-E011D9613C7B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Template.Perf", "perf\Azure.Template.Perf.csproj", "{6D3ADBD7-B0FA-4B4C-9FD4-A79B8B645467}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Test.Perf", "..\..\..\common\Perf\Azure.Test.Perf\Azure.Test.Perf.csproj", "{0ED9C8A0-9A19-4750-8DD3-61D086288283}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Template.Stress", "stress\Azure.Template.Stress.csproj", "{47E3BC66-5C4F-47CD-A37B-A973E54BCBA9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -23,38 +19,46 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E33D09D9-D809-472C-82E6-6A26BDB86FC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E33D09D9-D809-472C-82E6-6A26BDB86FC2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E33D09D9-D809-472C-82E6-6A26BDB86FC2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E33D09D9-D809-472C-82E6-6A26BDB86FC2}.Release|Any CPU.Build.0 = Release|Any CPU - {4F476D56-DDE7-43D3-8CB4-BA1E77F5A300}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F476D56-DDE7-43D3-8CB4-BA1E77F5A300}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F476D56-DDE7-43D3-8CB4-BA1E77F5A300}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F476D56-DDE7-43D3-8CB4-BA1E77F5A300}.Release|Any CPU.Build.0 = Release|Any CPU - {8052009B-2126-44A3-88CD-4F3B17894C64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8052009B-2126-44A3-88CD-4F3B17894C64}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8052009B-2126-44A3-88CD-4F3B17894C64}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8052009B-2126-44A3-88CD-4F3B17894C64}.Release|Any CPU.Build.0 = Release|Any CPU - {9CB28A07-1056-4FD8-BB26-A091AD95C08B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9CB28A07-1056-4FD8-BB26-A091AD95C08B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9CB28A07-1056-4FD8-BB26-A091AD95C08B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9CB28A07-1056-4FD8-BB26-A091AD95C08B}.Release|Any CPU.Build.0 = Release|Any CPU - {0B991CA1-E570-4292-BABF-E011D9613C7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0B991CA1-E570-4292-BABF-E011D9613C7B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0B991CA1-E570-4292-BABF-E011D9613C7B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0B991CA1-E570-4292-BABF-E011D9613C7B}.Release|Any CPU.Build.0 = Release|Any CPU - {6D3ADBD7-B0FA-4B4C-9FD4-A79B8B645467}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6D3ADBD7-B0FA-4B4C-9FD4-A79B8B645467}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6D3ADBD7-B0FA-4B4C-9FD4-A79B8B645467}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6D3ADBD7-B0FA-4B4C-9FD4-A79B8B645467}.Release|Any CPU.Build.0 = Release|Any CPU - {0ED9C8A0-9A19-4750-8DD3-61D086288283}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0ED9C8A0-9A19-4750-8DD3-61D086288283}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0ED9C8A0-9A19-4750-8DD3-61D086288283}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0ED9C8A0-9A19-4750-8DD3-61D086288283}.Release|Any CPU.Build.0 = Release|Any CPU - {AA507C7F-F19A-48AB-A7FA-CB113314418F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AA507C7F-F19A-48AB-A7FA-CB113314418F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AA507C7F-F19A-48AB-A7FA-CB113314418F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AA507C7F-F19A-48AB-A7FA-CB113314418F}.Release|Any CPU.Build.0 = Release|Any CPU + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0C276D1-2930-4887-B29A-D1A33E7009A2}.Release|Any CPU.Build.0 = Release|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E9A77AC-792A-4432-8320-ACFD46730401}.Release|Any CPU.Build.0 = Release|Any CPU + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Release|Any CPU.Build.0 = Release|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4241C1F-A53D-474C-9E4E-075054407E74}.Release|Any CPU.Build.0 = Release|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA8BD3F1-8616-47B6-974C-7576CDF4717E}.Release|Any CPU.Build.0 = Release|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85677AD3-C214-42FA-AE6E-49B956CAC8DC}.Release|Any CPU.Build.0 = Release|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Release|Any CPU.Build.0 = Release|Any CPU + {30C5FF85-655A-49FC-A324-16438130FF3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30C5FF85-655A-49FC-A324-16438130FF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30C5FF85-655A-49FC-A324-16438130FF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30C5FF85-655A-49FC-A324-16438130FF3F}.Release|Any CPU.Build.0 = Release|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Release|Any CPU.Build.0 = Release|Any CPU + {47E3BC66-5C4F-47CD-A37B-A973E54BCBA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47E3BC66-5C4F-47CD-A37B-A973E54BCBA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47E3BC66-5C4F-47CD-A37B-A973E54BCBA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47E3BC66-5C4F-47CD-A37B-A973E54BCBA9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/sdk/template/Azure.Template/CHANGELOG.md b/sdk/template/Azure.Template/CHANGELOG.md index 6b84171c88e0..0e50c409dcfa 100644 --- a/sdk/template/Azure.Template/CHANGELOG.md +++ b/sdk/template/Azure.Template/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History +## 1.0.3-beta.20 (2022-04-26) + +### Other Changes +- Release DPG library +- Add Grow-up story + ## 1.0.3-beta.19 (2020-09-24) - Test Submit-PR @@ -103,4 +109,4 @@ - Version Bump ## 1.0.2-preview.3 (2019-12-17) -- Started changelog to capture release notes. +- Started changelog to capture release notes. \ No newline at end of file diff --git a/sdk/template/Azure.Template/README.md b/sdk/template/Azure.Template/README.md index 6e9239574c11..efa7930b5893 100644 --- a/sdk/template/Azure.Template/README.md +++ b/sdk/template/Azure.Template/README.md @@ -1,24 +1,14 @@ -# README.md template - -Use the guidelines in each section of this template to ensure consistency and readability of your README. The README resides in your package's GitHub repository at the root of its directory within the repo. It's also used as the package distribution page (NuGet, PyPi, npm, etc.) and as a Quickstart on docs.microsoft.com. See [Azure.Template/README.md](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/README.md) for an example following this template. - -**Title**: The H1 of your README should be in the format: `# [Product Name] client library for [Language]` - -* All headings, including the H1, should use **sentence-style capitalization**. Refer to the [Microsoft Style Guide][style-guide-msft] and [Microsoft Cloud Style Guide][style-guide-cloud] for more information. -* Example: `# Azure Batch client library for Python` - # Azure Template client library for .NET -**Introduction**: The introduction appears directly under the title (H1) of your README. +Azure Template is a managed service that helps developers get secret simply and securely. + +Use the client library for to: -* **DO NOT** use an "Introduction" or "Overview" heading (H2) for this section. -* First sentence: **Describe the service** briefly. You can usually use the first line of the service's docs landing page for this (Example: [Cosmos DB docs landing page](https://docs.microsoft.com/azure/cosmos-db/)). -* Next, add a **bulleted list** of the **most common tasks** supported by the package or library, prefaced with "Use the client library for [Product Name] to:". Then, provide code snippets for these tasks in the [Examples](#examples) section later in the document. Keep the task list short but include those tasks most developers need to perform with your package. -* Include this single line of links targeting your product's content at the bottom of the introduction, making any adjustments as necessary (for example, NuGet instead of PyPi): +* [Get secret](https://docs.microsoft.com/azure) - [Source code](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/batch/azure-batch) | [Package (PyPi)](https://pypi.org/project/azure-batch/) | [API reference documentation](https://docs.microsoft.com/python/api/overview/azure/batch?view=azure-python) | [Product documentation](https://docs.microsoft.com/azure/batch/) +[Source code][source_root] | [Package (NuGet)][package] | [API reference documentation][reference_docs] | [Product documentation][azconfig_docs] | [Samples][source_samples] -> TIP: Your README should be as **brief** as possible but **no more brief** than necessary to get a developer new to Azure, the service, or the package up and running quickly. Keep it brief, but include everything a developer needs to make their first API call successfully. + [Source code](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/src) | [Package (NuGet)](https://www.nuget.org/packages) | [API reference documentation](https://azure.github.io/azure-sdk-for-net) | [Product documentation](https://docs.microsoft.com/azure) ## Getting started @@ -26,13 +16,19 @@ This section should include everything a developer needs to do to install and cr ### Install the package -First, provide instruction for obtaining and installing the package or library. This section might include only a single line of code, like `pip install package-name`, but should enable a developer to successfully install the package from NuGet, pip, npm, Maven, or even cloning a GitHub repository. +First, provide instruction for obtaining and installing the package or library. This section might include only a single line of code, like `dotnet add package package-name`, but should enable a developer to successfully install the package from NuGet, npm, or even cloning a GitHub repository. + +Install the client library for .NET with [NuGet](https://www.nuget.org/ ): + +```dotnetcli +dotnet add package Azure.Template --prerelease +``` ### Prerequisites Include a section after the install command that details any requirements that must be satisfied before a developer can [authenticate](#authenticate-the-client) and test all of the snippets in the [Examples](#examples) section. For example, for Cosmos DB: -> You must have an [Azure subscription](https://azure.microsoft.com/free/dotnet/), [Cosmos DB account](https://docs.microsoft.com/azure/cosmos-db/account-overview) (SQL API), and [Python 3.6+](https://www.python.org/downloads/) to use this package. +> You must have an [Azure subscription](https://azure.microsoft.com/free/dotnet/) and [Cosmos DB account](https://docs.microsoft.com/azure/cosmos-db/account-overview) (SQL API). In order to take advantage of the C# 8.0 syntax, it is recommended that you compile using the [.NET Core SDK](https://dotnet.microsoft.com/download) 3.0 or higher with a [language version](https://docs.microsoft.com/dotnet/csharp/language-reference/configure-language-version#override-a-default) of `latest`. It is also possible to compile with the .NET Core SDK 2.1.x using a language version of `preview`. ### Authenticate the client @@ -63,25 +59,17 @@ We guarantee that all client instance methods are thread-safe and independent of ## Examples -Include code snippets and short descriptions for each task you listed in the [Introduction](#introduction) (the bulleted list). Briefly explain each operation, but include enough clarity to explain complex or otherwise tricky operations. - -If possible, use the same example snippets that your in-code documentation uses. For example, use the snippets in your `examples.py` that Sphinx ingests via its [literalinclude](https://www.sphinx-doc.org/en/1.5/markup/code.html?highlight=code%20examples#includes) directive. The `examples.py` file containing the snippets should reside alongside your package's code, and should be tested in an automated fashion. - -Each example in the *Examples* section starts with an H3 that describes the example. At the top of this section, just under the *Examples* H2, add a bulleted list linking to each example H3. Each example should deep-link to the types and/or members used in the example. - -* [Create the thing](#create-the-thing) -* [Get the thing](#get-the-thing) -* [List the things](#list-the-things) +You can familiarize yourself with different APIs using [Samples](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/template/Azure.Template/samples). -### Get a secret +### Get secret The `GetSecret` method retrieves a secret from the service. ```C# Snippet:Azure_Template_GetSecret string endpoint = "https://myvault.vault.azure.net"; -var client = new MiniSecretClient(new Uri(endpoint), new DefaultAzureCredential()); +var client = new TemplateClient(endpoint, new DefaultAzureCredential()); -SecretBundle secret = client.GetSecret("TestSecret"); +SecretBundle secret = client.GetSecretValue("TestSecret"); Console.WriteLine(secret.Value); ```Python @@ -110,4 +98,4 @@ This is a template, but your SDK readme should include details on how to contrib [style-guide-msft]: https://docs.microsoft.com/style-guide/capitalization [style-guide-cloud]: https://aka.ms/azsdk/cloud-style-guide -![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net%2Fsdk%2Ftemplate%2FAzure.Template%2FREADME.png) +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net/sdk/template/Azure.Template/README.png) \ No newline at end of file diff --git a/sdk/template/Azure.Template/api/Azure.Template.netstandard2.0.cs b/sdk/template/Azure.Template/api/Azure.Template.netstandard2.0.cs index 2e0928c64dc7..75f92d49ef39 100644 --- a/sdk/template/Azure.Template/api/Azure.Template.netstandard2.0.cs +++ b/sdk/template/Azure.Template/api/Azure.Template.netstandard2.0.cs @@ -1,16 +1,18 @@ namespace Azure.Template { - public partial class MiniSecretClient + public partial class TemplateClient { - protected MiniSecretClient() { } - public MiniSecretClient(System.Uri endpoint, Azure.Core.TokenCredential credential) { } - public MiniSecretClient(System.Uri endpoint, Azure.Core.TokenCredential credential, Azure.Template.MiniSecretClientOptions options) { } - public virtual Azure.Response GetSecret(string secretName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.Task> GetSecretAsync(string secretName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + protected TemplateClient() { } + public TemplateClient(string vaultBaseUrl, Azure.Core.TokenCredential credential, Azure.Template.TemplateClientOptions options = null) { } + public virtual Azure.Core.Pipeline.HttpPipeline Pipeline { get { throw null; } } + public virtual Azure.Response GetSecret(string secretName, Azure.RequestContext context = null) { throw null; } + public virtual System.Threading.Tasks.Task GetSecretAsync(string secretName, Azure.RequestContext context = null) { throw null; } + public virtual Azure.Response GetSecretValue(string secretName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual System.Threading.Tasks.Task> GetSecretValueAsync(string secretName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class MiniSecretClientOptions : Azure.Core.ClientOptions + public partial class TemplateClientOptions : Azure.Core.ClientOptions { - public MiniSecretClientOptions(Azure.Template.MiniSecretClientOptions.ServiceVersion version = Azure.Template.MiniSecretClientOptions.ServiceVersion.V7_0) { } + public TemplateClientOptions(Azure.Template.TemplateClientOptions.ServiceVersion version = Azure.Template.TemplateClientOptions.ServiceVersion.V7_0) { } public enum ServiceVersion { V7_0 = 1, @@ -29,8 +31,4 @@ internal SecretBundle() { } public System.Collections.Generic.IReadOnlyDictionary Tags { get { throw null; } } public string Value { get { throw null; } } } - public static partial class TemplateModelFactory - { - public static Azure.Template.Models.SecretBundle SecretBundle(string value = null, string id = null, string contentType = null, System.Collections.Generic.IReadOnlyDictionary tags = null, string kid = null, bool? managed = default(bool?)) { throw null; } - } } diff --git a/sdk/template/Azure.Template/perf/MiniSecretClientTest.cs b/sdk/template/Azure.Template/perf/TemplateClientTest.cs similarity index 64% rename from sdk/template/Azure.Template/perf/MiniSecretClientTest.cs rename to sdk/template/Azure.Template/perf/TemplateClientTest.cs index 522bfe869f31..6c6b0f58f2a8 100644 --- a/sdk/template/Azure.Template/perf/MiniSecretClientTest.cs +++ b/sdk/template/Azure.Template/perf/TemplateClientTest.cs @@ -10,14 +10,14 @@ namespace Azure.Template.Perf { - public class MiniSecretClientTest : PerfTest + public class TemplateClientTest : PerfTest { - private readonly MiniSecretClient _miniSecretClient; + private readonly TemplateClient _templateClient; - public MiniSecretClientTest(MiniSecretClientOptions options) : base(options) + public TemplateClientTest(TemplateClientPerfOptions options) : base(options) { - var keyVaultUri = GetEnvironmentVariable("KEYVAULT_URL"); - _miniSecretClient = new MiniSecretClient(new Uri(keyVaultUri), new DefaultAzureCredential()); + string keyVaultUri = GetEnvironmentVariable("KEYVAULT_URL"); + _templateClient = new TemplateClient(keyVaultUri, new DefaultAzureCredential()); } public override void Run(CancellationToken cancellationToken) @@ -25,7 +25,7 @@ public override void Run(CancellationToken cancellationToken) // Throttle requests to avoid exceeding service limits Thread.Sleep(TimeSpan.FromMilliseconds(Options.Delay)); - _miniSecretClient.GetSecret(Options.SecretName, cancellationToken); + _templateClient.GetSecretValue(Options.SecretName, cancellationToken); } public override async Task RunAsync(CancellationToken cancellationToken) @@ -33,10 +33,10 @@ public override async Task RunAsync(CancellationToken cancellationToken) // Throttle requests to avoid exceeding service limits await Task.Delay(TimeSpan.FromMilliseconds(Options.Delay), cancellationToken); - await _miniSecretClient.GetSecretAsync(Options.SecretName, cancellationToken); + await _templateClient.GetSecretValueAsync(Options.SecretName, cancellationToken); } - public class MiniSecretClientOptions : PerfOptions + public class TemplateClientPerfOptions : PerfOptions { [Option("secret-name", Default = "TestSecret", HelpText = "Name of secret to get")] public string SecretName { get; set; } diff --git a/sdk/template/Azure.Template/samples/README.md b/sdk/template/Azure.Template/samples/README.md index 95ee7fd09ad2..0f7694be10f0 100644 --- a/sdk/template/Azure.Template/samples/README.md +++ b/sdk/template/Azure.Template/samples/README.md @@ -11,4 +11,7 @@ description: Samples for the Azure.Template client library. # Azure.Template Samples -- [Getting secrets](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/samples/Sample1_HelloWorld.md) +These code samples show common scenarios with the Azure Template client library. + +|[Sample1_HelloWorld](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorld.cs) |Get secrets synchronously.| +|[Sample1_HelloWorld_Async](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorldAsync.cs)] |Get secrets asynchronously.| diff --git a/sdk/template/Azure.Template/samples/Sample1.HelloWorldAsync.md b/sdk/template/Azure.Template/samples/Sample1.HelloWorldAsync.md new file mode 100644 index 000000000000..f09dbf761d1d --- /dev/null +++ b/sdk/template/Azure.Template/samples/Sample1.HelloWorldAsync.md @@ -0,0 +1,25 @@ +# Get secret asynchronously + +To use these samples, you'll first need to set up resources. See [getting started](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/README.md#getting-started) for details. + +## Import the namespaces + +```C# Snippet:Azure_Template +using Azure.Template.Models; +``` + +## Get secrets asynchronously + +You can also get secrets asynchronously: + +```C# Snippet:Azure_Template_GetSecretAsync +string endpoint = "https://myvault.vault.azure.net"; +var client = new TemplateClient(endpoint, new DefaultAzureCredential()); + +SecretBundle secret = await client.GetSecretValueAsync("TestSecret"); + +Console.WriteLine(secret.Value); +``` + +To see the full example source files, see: +* [HelloWorldAsync](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorldAsync.cs) \ No newline at end of file diff --git a/sdk/template/Azure.Template/samples/Sample1_HelloWorld.md b/sdk/template/Azure.Template/samples/Sample1_HelloWorld.md index 620840f80a42..bc9f9ba64196 100644 --- a/sdk/template/Azure.Template/samples/Sample1_HelloWorld.md +++ b/sdk/template/Azure.Template/samples/Sample1_HelloWorld.md @@ -1,10 +1,10 @@ -# Getting secrets +# Get secret To use these samples, you'll first need to set up resources. See [getting started](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/README.md#getting-started) for details. ## Import the namespaces -```C# Snippet:Azure_Template_Namespaces +```C# Snippet:Azure_Template using Azure.Template.Models; ``` @@ -14,22 +14,12 @@ You can create a client and get secrets synchronously: ```C# Snippet:Azure_Template_GetSecret string endpoint = "https://myvault.vault.azure.net"; -var client = new MiniSecretClient(new Uri(endpoint), new DefaultAzureCredential()); +var client = new TemplateClient(endpoint, new DefaultAzureCredential()); -SecretBundle secret = client.GetSecret("TestSecret"); +SecretBundle secret = client.GetSecretValue("TestSecret"); Console.WriteLine(secret.Value); ``` -## Get secrets asynchronously - -You can also get secrets asynchronously: - -```C# Snippet:Azure_Template_GetSecretAsync -string endpoint = "https://myvault.vault.azure.net"; -var client = new MiniSecretClient(new Uri(endpoint), new DefaultAzureCredential()); - -SecretBundle secret = await client.GetSecretAsync("TestSecret"); - -Console.WriteLine(secret.Value); -``` +To see the full example source files, see: +* [HelloWorld](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorld.cs) \ No newline at end of file diff --git a/sdk/template/Azure.Template/src/Azure.Template.csproj b/sdk/template/Azure.Template/src/Azure.Template.csproj index fcae6074b3fb..3862cda4a07b 100644 --- a/sdk/template/Azure.Template/src/Azure.Template.csproj +++ b/sdk/template/Azure.Template/src/Azure.Template.csproj @@ -1,22 +1,21 @@ - This is a template project to demonstrate how to create a package that uses code generation as well as use for testing our build and release pipelines - Azure SDK Template - 1.0.3-beta.19 + This is the Template client library for developing .NET applications with rich experience. + Azure SDK Code Generation Template for Azure Data Plane + 1.0.3-beta.20 Azure Template $(RequiredTargetFrameworks) true - - - - - + + + + - + \ No newline at end of file diff --git a/sdk/template/Azure.Template/src/Generated/TemplateClient.cs b/sdk/template/Azure.Template/src/Generated/TemplateClient.cs new file mode 100644 index 000000000000..e45e6ab8fcc7 --- /dev/null +++ b/sdk/template/Azure.Template/src/Generated/TemplateClient.cs @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.Template +{ + /// The Template service client. + public partial class TemplateClient + { + private static readonly string[] AuthorizationScopes = new string[] { "https://template/.default" }; + private readonly TokenCredential _tokenCredential; + private readonly HttpPipeline _pipeline; + private readonly string _vaultBaseUrl; + private readonly string _apiVersion; + + /// The ClientDiagnostics is used to provide tracing support for the client library. + internal ClientDiagnostics ClientDiagnostics { get; } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public virtual HttpPipeline Pipeline => _pipeline; + + /// Initializes a new instance of TemplateClient for mocking. + protected TemplateClient() + { + } + + /// Initializes a new instance of TemplateClient. + /// The vault name, for example https://myvault.vault.azure.net. + /// A credential used to authenticate to an Azure Service. + /// The options for configuring the client. + /// or is null. + public TemplateClient(string vaultBaseUrl, TokenCredential credential, TemplateClientOptions options = null) + { + Argument.AssertNotNull(vaultBaseUrl, nameof(vaultBaseUrl)); + Argument.AssertNotNull(credential, nameof(credential)); + options ??= new TemplateClientOptions(); + + ClientDiagnostics = new ClientDiagnostics(options); + _tokenCredential = credential; + _pipeline = HttpPipelineBuilder.Build(options, Array.Empty(), new HttpPipelinePolicy[] { new BearerTokenAuthenticationPolicy(_tokenCredential, AuthorizationScopes) }, new ResponseClassifier()); + _vaultBaseUrl = vaultBaseUrl; + _apiVersion = options.Version; + } + + /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. + /// The name of the secret. + /// The request context, which can override default behaviors on the request on a per-call basis. + /// is null. + /// is an empty string, and was expected to be non-empty. + /// + /// Schema for Response Body: + /// { + /// value: string, + /// id: string, + /// contentType: string, + /// tags: Dictionary<string, string>, + /// kid: string, + /// managed: boolean + /// } + /// + /// + /// + public virtual async Task GetSecretAsync(string secretName, RequestContext context = null) + { + Argument.AssertNotNullOrEmpty(secretName, nameof(secretName)); + + using var scope = ClientDiagnostics.CreateScope("TemplateClient.GetSecret"); + scope.Start(); + try + { + using HttpMessage message = CreateGetSecretRequest(secretName, context); + return await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. + /// The name of the secret. + /// The request context, which can override default behaviors on the request on a per-call basis. + /// is null. + /// is an empty string, and was expected to be non-empty. + /// + /// Schema for Response Body: + /// { + /// value: string, + /// id: string, + /// contentType: string, + /// tags: Dictionary<string, string>, + /// kid: string, + /// managed: boolean + /// } + /// + /// + /// + public virtual Response GetSecret(string secretName, RequestContext context = null) + { + Argument.AssertNotNullOrEmpty(secretName, nameof(secretName)); + + using var scope = ClientDiagnostics.CreateScope("TemplateClient.GetSecret"); + scope.Start(); + try + { + using HttpMessage message = CreateGetSecretRequest(secretName, context); + return _pipeline.ProcessMessage(message, context); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + internal HttpMessage CreateGetSecretRequest(string secretName, RequestContext context) + { + var message = _pipeline.CreateMessage(context, ResponseClassifier200); + var request = message.Request; + request.Method = RequestMethod.Get; + var uri = new RawRequestUriBuilder(); + uri.AppendRaw(_vaultBaseUrl, false); + uri.AppendPath("/secrets/", false); + uri.AppendPath(secretName, true); + uri.AppendQuery("api-version", _apiVersion, true); + request.Uri = uri; + request.Headers.Add("Accept", "application/json"); + return message; + } + + private static ResponseClassifier _responseClassifier200; + private static ResponseClassifier ResponseClassifier200 => _responseClassifier200 ??= new StatusCodeClassifier(stackalloc ushort[] { 200 }); + } +} diff --git a/sdk/template/Azure.Template/src/Generated/TemplateClientOptions.cs b/sdk/template/Azure.Template/src/Generated/TemplateClientOptions.cs new file mode 100644 index 000000000000..8e50363f92a8 --- /dev/null +++ b/sdk/template/Azure.Template/src/Generated/TemplateClientOptions.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Azure.Template +{ + /// Client options for TemplateClient. + public partial class TemplateClientOptions : ClientOptions + { + private const ServiceVersion LatestVersion = ServiceVersion.V7_0; + + /// The version of the service to use. + public enum ServiceVersion + { + /// Service version "7.0". + V7_0 = 1, + } + + internal string Version { get; } + + /// Initializes new instance of TemplateClientOptions. + public TemplateClientOptions(ServiceVersion version = LatestVersion) + { + Version = version switch + { + ServiceVersion.V7_0 => "7.0", + _ => throw new NotSupportedException() + }; + } + } +} diff --git a/sdk/template/Azure.Template/src/Generated/TemplateModelFactory.cs b/sdk/template/Azure.Template/src/Generated/TemplateModelFactory.cs deleted file mode 100644 index 0651f6954a9e..000000000000 --- a/sdk/template/Azure.Template/src/Generated/TemplateModelFactory.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// - -#nullable disable - -using System.Collections.Generic; - -namespace Azure.Template.Models -{ - /// Model factory for read-only models. - public static partial class TemplateModelFactory - { - /// Initializes a new instance of SecretBundle. - /// The secret value. - /// The secret id. - /// The content type of the secret. - /// Application specific metadata in the form of key-value pairs. - /// If this is a secret backing a KV certificate, then this field specifies the corresponding key backing the KV certificate. - /// True if the secret's lifetime is managed by key vault. If this is a secret backing a certificate, then managed will be true. - /// A new instance for mocking. - public static SecretBundle SecretBundle(string value = null, string id = null, string contentType = null, IReadOnlyDictionary tags = null, string kid = null, bool? managed = null) - { - tags ??= new Dictionary(); - - return new SecretBundle(value, id, contentType, tags, kid, managed); - } - } -} diff --git a/sdk/template/Azure.Template/src/Generated/TemplateRestClient.cs b/sdk/template/Azure.Template/src/Generated/TemplateRestClient.cs deleted file mode 100644 index 13b9a179008c..000000000000 --- a/sdk/template/Azure.Template/src/Generated/TemplateRestClient.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// - -#nullable disable - -using System; -using System.Text.Json; -using System.Threading; -using System.Threading.Tasks; -using Azure; -using Azure.Core; -using Azure.Core.Pipeline; -using Azure.Template.Models; - -namespace Azure.Template -{ - internal partial class TemplateRestClient - { - private readonly HttpPipeline _pipeline; - private readonly string _vaultBaseUrl; - private readonly string _apiVersion; - - /// The ClientDiagnostics is used to provide tracing support for the client library. - internal ClientDiagnostics ClientDiagnostics { get; } - - /// Initializes a new instance of TemplateRestClient. - /// The handler for diagnostic messaging in the client. - /// The HTTP pipeline for sending and receiving REST requests and responses. - /// The vault name, for example https://myvault.vault.azure.net. - /// Api Version. - /// , , or is null. - public TemplateRestClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, string vaultBaseUrl, string apiVersion = "7.0") - { - ClientDiagnostics = clientDiagnostics ?? throw new ArgumentNullException(nameof(clientDiagnostics)); - _pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline)); - _vaultBaseUrl = vaultBaseUrl ?? throw new ArgumentNullException(nameof(vaultBaseUrl)); - _apiVersion = apiVersion ?? throw new ArgumentNullException(nameof(apiVersion)); - } - - internal HttpMessage CreateGetSecretRequest(string secretName) - { - var message = _pipeline.CreateMessage(); - var request = message.Request; - request.Method = RequestMethod.Get; - var uri = new RawRequestUriBuilder(); - uri.AppendRaw(_vaultBaseUrl, false); - uri.AppendPath("/secrets/", false); - uri.AppendPath(secretName, true); - uri.AppendQuery("api-version", _apiVersion, true); - request.Uri = uri; - request.Headers.Add("Accept", "application/json"); - return message; - } - - /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. - /// The name of the secret. - /// The cancellation token to use. - /// is null. - public async Task> GetSecretAsync(string secretName, CancellationToken cancellationToken = default) - { - if (secretName == null) - { - throw new ArgumentNullException(nameof(secretName)); - } - - using var message = CreateGetSecretRequest(secretName); - await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false); - switch (message.Response.Status) - { - case 200: - { - SecretBundle value = default; - using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false); - value = SecretBundle.DeserializeSecretBundle(document.RootElement); - return Response.FromValue(value, message.Response); - } - default: - throw await ClientDiagnostics.CreateRequestFailedExceptionAsync(message.Response).ConfigureAwait(false); - } - } - - /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. - /// The name of the secret. - /// The cancellation token to use. - /// is null. - public Response GetSecret(string secretName, CancellationToken cancellationToken = default) - { - if (secretName == null) - { - throw new ArgumentNullException(nameof(secretName)); - } - - using var message = CreateGetSecretRequest(secretName); - _pipeline.Send(message, cancellationToken); - switch (message.Response.Status) - { - case 200: - { - SecretBundle value = default; - using var document = JsonDocument.Parse(message.Response.ContentStream); - value = SecretBundle.DeserializeSecretBundle(document.RootElement); - return Response.FromValue(value, message.Response); - } - default: - throw ClientDiagnostics.CreateRequestFailedException(message.Response); - } - } - } -} diff --git a/sdk/template/Azure.Template/src/MiniSecretClient.cs b/sdk/template/Azure.Template/src/MiniSecretClient.cs deleted file mode 100644 index faa70dd28489..000000000000 --- a/sdk/template/Azure.Template/src/MiniSecretClient.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Threading; -using System.Threading.Tasks; -using Azure.Core; -using Azure.Core.Pipeline; -using Azure.Template.Models; - -namespace Azure.Template -{ - /// - /// The sample secrets client. - /// - public class MiniSecretClient - { - private readonly ClientDiagnostics _clientDiagnostics; - private readonly HttpPipeline _pipeline; - internal TemplateRestClient RestClient { get; } - - /// - /// Initializes a new instance of the . - /// - public MiniSecretClient(Uri endpoint, TokenCredential credential) : this(endpoint, credential, new MiniSecretClientOptions()) - { - } - - /// - /// Initializes a new instance of the . - /// - public MiniSecretClient(Uri endpoint, TokenCredential credential, MiniSecretClientOptions options): this( - new ClientDiagnostics(options), - HttpPipelineBuilder.Build(options, new BearerTokenAuthenticationPolicy(credential, "https://vault.azure.net/.default")), - endpoint.AbsoluteUri, - options.Version) - { - } - - /// Initializes a new instance of MiniSecretClient for mocking. - protected MiniSecretClient() - { - } - /// Initializes a new instance of MiniSecretClient. - /// The handler for diagnostic messaging in the client. - /// The HTTP pipeline for sending and receiving REST requests and responses. - /// The vault name, for example https://myvault.vault.azure.net. - /// Api Version. - internal MiniSecretClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, string vaultBaseUrl, string apiVersion = "7.0") - { - RestClient = new TemplateRestClient(clientDiagnostics, pipeline, vaultBaseUrl, apiVersion); - _clientDiagnostics = clientDiagnostics; - _pipeline = pipeline; - } - - /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. - /// The name of the secret. - /// The cancellation token to use. - public virtual async Task> GetSecretAsync(string secretName, CancellationToken cancellationToken = default) - { - using var scope = _clientDiagnostics.CreateScope("MiniSecretClient.GetSecret"); - scope.Start(); - try - { - return await RestClient.GetSecretAsync(secretName, cancellationToken).ConfigureAwait(false); - } - catch (Exception e) - { - scope.Failed(e); - throw; - } - } - - /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. - /// The name of the secret. - /// The cancellation token to use. - public virtual Response GetSecret(string secretName, CancellationToken cancellationToken = default) - { - using var scope = _clientDiagnostics.CreateScope("MiniSecretClient.GetSecret"); - scope.Start(); - try - { - return RestClient.GetSecret(secretName, cancellationToken); - } - catch (Exception e) - { - scope.Failed(e); - throw; - } - } - } -} diff --git a/sdk/template/Azure.Template/src/MiniSecretClientOptions.cs b/sdk/template/Azure.Template/src/MiniSecretClientOptions.cs deleted file mode 100644 index 1936dccc9d8e..000000000000 --- a/sdk/template/Azure.Template/src/MiniSecretClientOptions.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Azure.Core; - -namespace Azure.Template -{ - /// - /// The options for - /// - public class MiniSecretClientOptions : ClientOptions - { - internal string Version { get; } - - /// - /// Initializes a new instance of the . - /// - public MiniSecretClientOptions(ServiceVersion version = ServiceVersion.V7_0) - { - Version = version switch - { - ServiceVersion.V7_0 => "7.0", - _ => throw new ArgumentException($"The service version {version} is not supported by this library.", nameof(version)) - }; - } - - /// - /// The template service version. - /// - public enum ServiceVersion - { - /// - /// The 7.0 of the secret service. - /// -#pragma warning disable CA1707 // Remove the underscores from member name - V7_0 = 1 -#pragma warning restore - } - } -} \ No newline at end of file diff --git a/sdk/template/Azure.Template/src/Generated/Models/SecretBundle.Serialization.cs b/sdk/template/Azure.Template/src/Models/SecretBundle.Serialization.cs similarity index 92% rename from sdk/template/Azure.Template/src/Generated/Models/SecretBundle.Serialization.cs rename to sdk/template/Azure.Template/src/Models/SecretBundle.Serialization.cs index fd838a415646..0c1f66b97101 100644 --- a/sdk/template/Azure.Template/src/Generated/Models/SecretBundle.Serialization.cs +++ b/sdk/template/Azure.Template/src/Models/SecretBundle.Serialization.cs @@ -71,5 +71,11 @@ internal static SecretBundle DeserializeSecretBundle(JsonElement element) } return new SecretBundle(value.Value, id.Value, contentType.Value, Optional.ToDictionary(tags), kid.Value, Optional.ToNullable(managed)); } + + internal static SecretBundle FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeSecretBundle(document.RootElement); + } } } diff --git a/sdk/template/Azure.Template/src/Generated/Models/SecretBundle.cs b/sdk/template/Azure.Template/src/Models/SecretBundle.cs similarity index 100% rename from sdk/template/Azure.Template/src/Generated/Models/SecretBundle.cs rename to sdk/template/Azure.Template/src/Models/SecretBundle.cs diff --git a/sdk/template/Azure.Template/src/TemplateClient.cs b/sdk/template/Azure.Template/src/TemplateClient.cs new file mode 100644 index 000000000000..aaf2c58f5374 --- /dev/null +++ b/sdk/template/Azure.Template/src/TemplateClient.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable disable + +using System; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; +using Azure.Template.Models; + +namespace Azure.Template +{ + /// The Template service client. + public partial class TemplateClient + { + /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. + /// The name of the secret. + /// The cancellation token to use. + public virtual async Task> GetSecretValueAsync(string secretName, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = ClientDiagnostics.CreateScope("TemplateClient.GetSecretValue"); + scope.Start(); + + try + { + RequestContext context = new RequestContext() + { + CancellationToken = cancellationToken, + }; + Response response = await GetSecretAsync(secretName, context).ConfigureAwait(false); + SecretBundle value = SecretBundle.FromResponse(response); + return Response.FromValue(value, response); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. + /// The name of the secret. + /// The cancellation token to use. + public virtual Response GetSecretValue(string secretName, CancellationToken cancellationToken = default) + { + using DiagnosticScope scope = ClientDiagnostics.CreateScope("TemplateClient.GetSecretValue"); + scope.Start(); + + try + { + RequestContext context = new RequestContext() + { + CancellationToken = cancellationToken, + }; + Response response = GetSecret(secretName, context); + SecretBundle value = SecretBundle.FromResponse(response); + return Response.FromValue(value, response); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + } +} diff --git a/sdk/template/Azure.Template/src/autorest.md b/sdk/template/Azure.Template/src/autorest.md index 52b44c1408a9..79ee36d5d3ad 100644 --- a/sdk/template/Azure.Template/src/autorest.md +++ b/sdk/template/Azure.Template/src/autorest.md @@ -1,9 +1,15 @@ -# Generated code configuration +# Azure SDK Code Generation for Data Plane Run `dotnet build /t:GenerateCode` to generate code. +### AutoRest Configuration +> see https://aka.ms/autorest + ``` yaml input-file: - - $(this-folder)/swagger/mini-secrets.json -generation1-convenience-client: true +- $(this-folder)/swagger/mini-secrets.json +namespace: Azure.Template +security: AADToken +security-scopes: https://template/.default + ``` diff --git a/sdk/template/Azure.Template/src/properties/AssemblyInfo.cs b/sdk/template/Azure.Template/src/properties/AssemblyInfo.cs index 5f56dad95a69..9b5ade43f66d 100644 --- a/sdk/template/Azure.Template/src/properties/AssemblyInfo.cs +++ b/sdk/template/Azure.Template/src/properties/AssemblyInfo.cs @@ -5,9 +5,9 @@ // Replace with test project/test project public key and uncomment to make internal members visible to // your test project. If not needed, this can be deleted. -// [assembly: InternalsVisibleTo("Azure.Template.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d15ddcb29688295338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593daa7b11b4")] +// [assembly: InternalsVisibleTo("Azure.Template.Generated.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d15ddcb29688295338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593daa7b11b4")] // Replace Microsoft.Test with the correct resource provider namepace for your service and uncomment. // See https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-services-resource-providers // for the list of possible values. -[assembly: Azure.Core.AzureResourceProviderNamespace("Microsoft.Test")] +[assembly: Azure.Core.AzureResourceProviderNamespace("Microsoft.Template")] diff --git a/sdk/template/Azure.Template/stress/MiniSecretClientTest.cs b/sdk/template/Azure.Template/stress/TemplateClientTest.cs similarity index 71% rename from sdk/template/Azure.Template/stress/MiniSecretClientTest.cs rename to sdk/template/Azure.Template/stress/TemplateClientTest.cs index 8217e5c16f35..77287537675e 100644 --- a/sdk/template/Azure.Template/stress/MiniSecretClientTest.cs +++ b/sdk/template/Azure.Template/stress/TemplateClientTest.cs @@ -7,19 +7,20 @@ using Azure.Identity; using Azure.Test.Stress; using CommandLine; +using Azure.Template.Models; namespace Azure.Template.Stress { - public class MiniSecretClientTest : StressTest + public class TemplateClientTest : StressTest { - public MiniSecretClientTest(MiniSecretClientOptions options, MiniSecretClientMetrics metrics) : base(options, metrics) + public TemplateClientTest(TemplateClientStressOptions options, TemplateClientStressMetrics metrics) : base(options, metrics) { } public override async Task RunAsync(CancellationToken cancellationToken) { - var keyVaultUri = GetEnvironmentVariable("KEYVAULT_URL"); - var client = new MiniSecretClient(new Uri(keyVaultUri), new DefaultAzureCredential()); + string keyVaultUri = GetEnvironmentVariable("KEYVAULT_URL"); + TemplateClient client = new TemplateClient(keyVaultUri, new DefaultAzureCredential()); while (!cancellationToken.IsCancellationRequested) { @@ -28,7 +29,7 @@ public override async Task RunAsync(CancellationToken cancellationToken) // Throttle requests to avoid exceeding service limits await Task.Delay(TimeSpan.FromMilliseconds(Options.Delay), cancellationToken); - var secret = await client.GetSecretAsync(Options.SecretName, cancellationToken); + Response secret = await client.GetSecretValueAsync(Options.SecretName, cancellationToken); Interlocked.Increment(ref Metrics.SecretsReceived); if (secret.Value.Value == "TestValue") @@ -50,14 +51,14 @@ public override async Task RunAsync(CancellationToken cancellationToken) } } - public class MiniSecretClientMetrics : StressMetrics + public class TemplateClientStressMetrics : StressMetrics { public long SecretsReceived; public long CorrectValues; public long IncorrectValues; } - public class MiniSecretClientOptions : StressOptions + public class TemplateClientStressOptions : StressOptions { [Option("secret-name", Default = "TestSecret", HelpText = "Name of secret to get")] public string SecretName { get; set; } diff --git a/sdk/template/Azure.Template/tests/Azure.Template.Tests.csproj b/sdk/template/Azure.Template/tests/Azure.Template.Tests.csproj index b78903be3c1a..8f392bf81163 100644 --- a/sdk/template/Azure.Template/tests/Azure.Template.Tests.csproj +++ b/sdk/template/Azure.Template/tests/Azure.Template.Tests.csproj @@ -1,8 +1,17 @@  $(RequiredTargetFrameworks) + + + $(NoWarn);CS1591 + + + + + + @@ -11,7 +20,11 @@ - - + + + + + + - + \ No newline at end of file diff --git a/sdk/template/Azure.Template/tests/Samples/MiniSecretClientSamples.HelloWorld.cs b/sdk/template/Azure.Template/tests/Samples/MiniSecretClientSamples.HelloWorld.cs deleted file mode 100644 index 774ff3630835..000000000000 --- a/sdk/template/Azure.Template/tests/Samples/MiniSecretClientSamples.HelloWorld.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Threading.Tasks; -using Azure.Core.TestFramework; -using Azure.Identity; -#region Snippet:Azure_Template_Namespaces -using Azure.Template.Models; -#endregion -using NUnit.Framework; - -namespace Azure.Template.Tests.Samples -{ - public class MiniSecretClientSamples: SamplesBase - { - [Test] - [SyncOnly] - public void GettingASecret() - { - var endpoint = TestEnvironment.KeyVaultUri; - - #region Snippet:Azure_Template_GetSecret -#if SNIPPET - string endpoint = "https://myvault.vault.azure.net"; -#endif - var client = new MiniSecretClient(new Uri(endpoint), new DefaultAzureCredential()); - - SecretBundle secret = client.GetSecret("TestSecret"); - - Console.WriteLine(secret.Value); - #endregion - - Assert.NotNull(secret.Value); - } - - [Test] - [AsyncOnly] - public async Task GettingASecretAsync() - { - var endpoint = TestEnvironment.KeyVaultUri; - - #region Snippet:Azure_Template_GetSecretAsync -#if SNIPPET - string endpoint = "https://myvault.vault.azure.net"; -#endif - var client = new MiniSecretClient(new Uri(endpoint), new DefaultAzureCredential()); - - SecretBundle secret = await client.GetSecretAsync("TestSecret"); - - Console.WriteLine(secret.Value); - #endregion - - Assert.NotNull(secret.Value); - } - } -} diff --git a/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorld.cs b/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorld.cs new file mode 100644 index 000000000000..0375a7ca841c --- /dev/null +++ b/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorld.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure.Core.TestFramework; +using Azure.Identity; +#region Snippet:Azure_Template +using Azure.Template.Models; +#endregion +using NUnit.Framework; + +namespace Azure.Template.Tests.Samples +{ + public partial class TemplateSamples: SamplesBase + { + [Test] + [SyncOnly] + public void GettingASecret() + { + #region Snippet:Azure_Template_GetSecret + string endpoint = "https://myvault.vault.azure.net"; +#if !SNIPPET + endpoint = TestEnvironment.KeyVaultUri; +#endif + var client = new TemplateClient(endpoint, new DefaultAzureCredential()); + + SecretBundle secret = client.GetSecretValue("TestSecret"); + + Console.WriteLine(secret.Value); + #endregion + + Assert.NotNull(secret.Value); + } + } +} diff --git a/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorldAsync.cs b/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorldAsync.cs new file mode 100644 index 000000000000..b0f10fb15c94 --- /dev/null +++ b/sdk/template/Azure.Template/tests/Samples/Sample1_HelloWorldAsync.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure.Core.TestFramework; +using Azure.Identity; +using Azure.Template.Models; +using NUnit.Framework; + +namespace Azure.Template.Tests.Samples +{ + public partial class TemplateSamples: SamplesBase + { + [Test] + [AsyncOnly] + public async Task GettingASecretAsync() + { + #region Snippet:Azure_Template_GetSecretAsync + string endpoint = "https://myvault.vault.azure.net"; +#if !SNIPPET + endpoint = TestEnvironment.KeyVaultUri; +#endif + var client = new TemplateClient(endpoint, new DefaultAzureCredential()); + + SecretBundle secret = await client.GetSecretValueAsync("TestSecret"); + + Console.WriteLine(secret.Value); + #endregion + + Assert.NotNull(secret.Value); + } + } +} diff --git a/sdk/template/Azure.Template/tests/SessionRecords/MiniSecretClientLiveTests/CanGetSecret.json b/sdk/template/Azure.Template/tests/SessionRecords/TemplateClientLiveTests/CanGetSecret.json similarity index 100% rename from sdk/template/Azure.Template/tests/SessionRecords/MiniSecretClientLiveTests/CanGetSecret.json rename to sdk/template/Azure.Template/tests/SessionRecords/TemplateClientLiveTests/CanGetSecret.json diff --git a/sdk/template/Azure.Template/tests/SessionRecords/MiniSecretClientLiveTests/CanGetSecretAsync.json b/sdk/template/Azure.Template/tests/SessionRecords/TemplateClientLiveTests/CanGetSecretAsync.json similarity index 100% rename from sdk/template/Azure.Template/tests/SessionRecords/MiniSecretClientLiveTests/CanGetSecretAsync.json rename to sdk/template/Azure.Template/tests/SessionRecords/TemplateClientLiveTests/CanGetSecretAsync.json diff --git a/sdk/template/Azure.Template/tests/MiniSecretClientLiveTests.cs b/sdk/template/Azure.Template/tests/TemplateClientLiveTests.cs similarity index 67% rename from sdk/template/Azure.Template/tests/MiniSecretClientLiveTests.cs rename to sdk/template/Azure.Template/tests/TemplateClientLiveTests.cs index 2f3b842e2c49..c3b9c332ba60 100644 --- a/sdk/template/Azure.Template/tests/MiniSecretClientLiveTests.cs +++ b/sdk/template/Azure.Template/tests/TemplateClientLiveTests.cs @@ -5,14 +5,15 @@ using System.Threading.Tasks; using Azure.Core.TestFramework; using NUnit.Framework; +using Azure.Template.Models; namespace Azure.Template.Tests { // When necessary, use the [ClientTestFixture] to test multiple versions. // See https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/core/Azure.Core.TestFramework#support-multi-service-version-testing. - public class MiniSecretClientLiveTests: RecordedTestBase + public class TemplateClientLiveTests: RecordedTestBase { - public MiniSecretClientLiveTests(bool isAsync) + public TemplateClientLiveTests(bool isAsync) // Delete null and the opening comment to re-record, or change to debug live tests. // You can also change eng/nunit.runsettings to set the TestMode parameter. // See https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/core/Azure.Core.TestFramework#test-settings. @@ -20,21 +21,21 @@ public MiniSecretClientLiveTests(bool isAsync) { } - private MiniSecretClient CreateClient() + private TemplateClient CreateClient() { - return InstrumentClient(new MiniSecretClient( - new Uri(TestEnvironment.KeyVaultUri), + return InstrumentClient(new TemplateClient( + TestEnvironment.KeyVaultUri, TestEnvironment.Credential, - InstrumentClientOptions(new MiniSecretClientOptions()) + InstrumentClientOptions(new TemplateClientOptions()) )); } [RecordedTest] public async Task CanGetSecret() { - var client = CreateClient(); + TemplateClient client = CreateClient(); - var secret = await client.GetSecretAsync("TestSecret"); + Response secret = await client.GetSecretValueAsync("TestSecret"); Assert.AreEqual("Very secret value", secret.Value.Value); } diff --git a/sdk/template/Azure.Template/tests/MiniSecretClientTestEnvironment.cs b/sdk/template/Azure.Template/tests/TemplateClientTestEnvironment.cs similarity index 91% rename from sdk/template/Azure.Template/tests/MiniSecretClientTestEnvironment.cs rename to sdk/template/Azure.Template/tests/TemplateClientTestEnvironment.cs index 344662a88cfb..2fb75b1d747a 100644 --- a/sdk/template/Azure.Template/tests/MiniSecretClientTestEnvironment.cs +++ b/sdk/template/Azure.Template/tests/TemplateClientTestEnvironment.cs @@ -5,7 +5,7 @@ namespace Azure.Template.Tests { - public class MiniSecretClientTestEnvironment : TestEnvironment + public class TemplateClientTestEnvironment : TestEnvironment { public string KeyVaultUri => GetRecordedVariable("KEYVAULT_URL"); diff --git a/sdk/template/ci.yml b/sdk/template/ci.yml index 416c4a8f56b3..1be91ba013d8 100644 --- a/sdk/template/ci.yml +++ b/sdk/template/ci.yml @@ -1,4 +1,5 @@ # NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. + trigger: branches: include: @@ -25,18 +26,9 @@ pr: paths: include: - sdk/template/ -#if (false) - # The following paths should only be included in template/ci.yml, and removed from any other SDKs which copy this file. - # The surrounding conditions should accomplish that when installed with `dotnet new azsdk`. - # eng/common code changes trigger template pipeline for basic checking. - - eng/common/ - - common/Perf/ - - common/PerfStressShared/ - - common/Stress/ -#endif extends: - template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml + template: /eng/pipelines/templates/stages/archetype-sdk-client.yml parameters: ServiceDirectory: template ArtifactName: packages diff --git a/sdk/template/tests.yml b/sdk/template/tests.yml index a64b721ac4c8..6c539b353599 100644 --- a/sdk/template/tests.yml +++ b/sdk/template/tests.yml @@ -1,6 +1,7 @@ trigger: none extends: - template: ../../eng/pipelines/templates/stages/archetype-sdk-tests.yml + template: /eng/pipelines/templates/stages/archetype-sdk-tests.yml parameters: ServiceDirectory: template + SupportedClouds: 'Public'