This commit is contained in:
Justin Yoo 2020-10-11 18:19:31 +09:00 коммит произвёл GitHub
Родитель 629de2483b
Коммит 19c322e401
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
29 изменённых файлов: 472 добавлений и 389 удалений

17
.github/workflows/build.yaml поставляемый
Просмотреть файл

@ -12,8 +12,8 @@ jobs:
name: Build and test
strategy:
matrix:
os: [ 'windows-latest' ]
dotnet: [ '3.1.401' ]
os: [ 'windows-latest', 'macos-latest', 'ubuntu-latest' ]
dotnet: [ '3.1.402' ]
runs-on: ${{ matrix.os }}
@ -21,13 +21,18 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Setup .NET SDK
- name: Setup .NET SDK 2.1 LTS
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
dotnet-version: '2.1.x'
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Setup .NET SDK 3.1 LTS
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'
# - name: Add MSBuild to PATH
# uses: microsoft/setup-msbuild@v1.0.0
- name: Restore NuGet packages
shell: pwsh

17
.github/workflows/pr.yaml поставляемый
Просмотреть файл

@ -10,8 +10,8 @@ jobs:
name: Build and test
strategy:
matrix:
os: [ 'windows-latest' ]
dotnet: [ '3.1.401' ]
os: [ 'windows-latest', 'macos-latest', 'ubuntu-latest' ]
dotnet: [ '3.1.402' ]
runs-on: ${{ matrix.os }}
@ -19,13 +19,18 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Setup .NET SDK
- name: Setup .NET SDK 2.1 LTS
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
dotnet-version: '2.1.x'
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Setup .NET SDK 3.1 LTS
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'
# - name: Add MSBuild to PATH
# uses: microsoft/setup-msbuild@v1.0.0
- name: Restore NuGet packages
shell: pwsh

20
.github/workflows/release-all.yaml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@ jobs:
strategy:
matrix:
os: [ 'windows-latest' ]
dotnet: [ '3.1.401' ]
dotnet: [ '3.1.402' ]
runs-on: ${{ matrix.os }}
@ -50,13 +50,23 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Setup .NET SDK
# - name: Setup .NET SDK
# uses: actions/setup-dotnet@v1
# with:
# dotnet-version: ${{ matrix.dotnet }}
- name: Setup .NET SDK 2.1 LTS
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
dotnet-version: '2.1.x'
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Setup .NET SDK 3.1 LTS
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'
# - name: Add MSBuild to PATH
# uses: microsoft/setup-msbuild@v1.0.0
- name: Restore NuGet packages
shell: pwsh

24
.github/workflows/release-cli.yaml поставляемый
Просмотреть файл

@ -12,7 +12,7 @@ jobs:
matrix:
os: [ 'windows-latest' ]
node: [ 10 ]
dotnet: [ '3.1.401' ]
dotnet: [ '3.1.402' ]
targetFramework: [ 'netcoreapp3.1' ]
runtime: [ 'win-x64', 'linux-x64', 'osx-x64' ]
@ -60,15 +60,27 @@ jobs:
# with:
# node-version: ${{ matrix.node }}
- name: Setup .NET SDK
# - name: Setup .NET SDK
# if: steps.release.outputs.module == 'cli'
# uses: actions/setup-dotnet@v1
# with:
# dotnet-version: ${{ matrix.dotnet }}
- name: Setup .NET SDK 2.1 LTS
if: steps.release.outputs.module == 'cli'
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
dotnet-version: '2.1.x'
- name: Add MSBuild to PATH
- name: Setup .NET SDK 3.1 LTS
if: steps.release.outputs.module == 'cli'
uses: microsoft/setup-msbuild@v1.0.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'
# - name: Add MSBuild to PATH
# if: steps.release.outputs.module == 'cli'
# uses: microsoft/setup-msbuild@v1.0.0
- name: Restore NuGet packages
if: steps.release.outputs.module == 'cli'
@ -136,7 +148,7 @@ jobs:
matrix:
os: [ 'ubuntu-latest' ]
node: [ 10 ]
dotnet: [ '3.1.401' ]
dotnet: [ '3.1.402' ]
# targetFramework: [ 'net461', 'netcoreapp3.1' ]
# runtime: [ 'win-x64', 'linux-x64', 'osx-x64' ]

6
.vscode/extensions.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
{
"recommendations": [
"ms-azuretools.vscode-azurefunctions",
"ms-dotnettools.csharp"
]
}

33
.vscode/launch.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,33 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": "Azure Functions Launch",
"type": "coreclr",
"request": "attach",
"processId": "${command:azureFunctions.pickProcess}"
},
{
"name": "Azure Functions CLI Launch",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI/bin/Debug/netcoreapp3.1/azfuncopenapi.dll",
"args": [],
"cwd": "${workspaceFolder}/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

7
.vscode/settings.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
{
"azureFunctions.deploySubpath": "bin/Release/netcoreapp3.1/publish",
"azureFunctions.projectLanguage": "C#",
"azureFunctions.projectRuntime": "~3",
"debug.internalConsoleOptions": "neverOpen",
"azureFunctions.preDeployTask": "publish"
}

89
.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,89 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "clean",
"command": "dotnet",
"args": [
"clean",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"type": "process",
"problemMatcher": "$msCompile"
},
{
"label": "build",
"command": "dotnet",
"args": [
"build",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"type": "process",
"dependsOn": "clean",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": "$msCompile"
},
{
"label": "clean release",
"command": "dotnet",
"args": [
"clean",
"--configuration",
"Release",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"type": "process",
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"args": [
"publish",
// "${workspaceFolder}/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/Microsoft.Azure.WebJobs.Extensions.OpenApi.csproj",
// "${workspaceFolder}/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings/Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.csproj",
"${workspaceFolder}/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.csproj",
// "${workspaceFolder}/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.csproj",
"--configuration",
"Release",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"type": "process",
"dependsOn": "clean release",
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"type": "func",
"dependsOn": "build",
"options": {
// "cwd": "${workspaceFolder}/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2IoC/bin/Debug/netcoreapp2.1"
// "cwd": "${workspaceFolder}/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2Static/bin/Debug/netcoreapp2.1"
"cwd": "${workspaceFolder}/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC/bin/Debug/netcoreapp3.1"
// "cwd": "${workspaceFolder}/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static/bin/Debug/netcoreapp3.1"
},
"command": "host start",
"isBackground": true,
"problemMatcher": "$func-watch"
}
]
}

Просмотреть файл

@ -1,5 +1,36 @@
# Azure Functions Open API Extension #
# Contributing
## Acknowledgement ##
* [Swagger UI](https://github.com/swagger-api/swagger-ui) version used for this library is [3.20.5](https://github.com/swagger-api/swagger-ui/releases/tag/v3.20.5) under the [Apache 2.0 license](https://opensource.org/licenses/Apache-2.0).
## Getting Started ##
* [Enable Open API documents to your Azure Functions HTTP Trigger](docs/enable-open-api-endpoints.md)
* [Integrating Open API-enabled Azure Functions to Azure API Management](docs/integrate-with-apim.md)
* [Integrating Open API-enabled Azure Functions to Power Platform](docs/integrate-with-powerplatform.md)
## Sample Azure Function Apps with Open API Metadata Enabled ##
* [Function App v2 static](samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2Static)
* [Function App v2 IoC](samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2IoC)
* [Function App v3 static](samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static)
* [Function App v3 IoC](samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC)
## Azure Functions V1 Support ##
This library supports Azure Functions V2 and onwards. If you still want to get your v1 app supported, find the [community contribution](https://github.com/aliencube/AzureFunctions.Extensions).
## Issues? ##
While using this library, if you find any issue, please raise an issue on the [Issue](https://github.com/Azure/azure-functions-openapi-extension/issues) page.
## Contributing ##
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us

Просмотреть файл

@ -0,0 +1,238 @@
# Enable Open API Endpoints on Azure Functions #
[Open API metadata][openapi] supports in Azure Functions is now available with this extension, [Azure Functions Open API Extension][az func openapi extension]. With this extension, you can directly let your API endpoints be discoverable.
> [!IMPORTANT]
> This extension supports only Azure Functions v2 and onwards. If you want to get your Azure Functions v1 supported, find [this preview document][az func openapi v1 preview] or [community contribution][az func openapi community].
[Open API metadata][openapi] allows wide variety of other software and applications to consume an Azure Functions app hosting HTTP APIs. The software and applications include Microsoft products and services like [Power Platform][power platform], [API Management][az apim] and third-party tools like [Postman][postman].
## Prerequisites ##
To get yourself started, you need to have the followings installed on your local machine.
> [!IMPORTANT]
> This extension is currently available in .NET Core runtime.
* [.NET Core SDK 3.1 LTS][dotnet core sdk]
* [Azure Functions Core Tools][az func core tools]
* [Visual Studio Code][vs code]
* [Visual Studio Extensions for Azure Tools][vs code azure tools]
* [Free Microsoft Azure Account][az account free]
## Create Function App ##
Firs of all, [create a function app on your local machine][az func create].
```bash
func init MyOpenApiFunctionApp --dotnet
```
Navigate to the project directory
```bash
cd MyOpenApiFunctionApp
```
Add a function to your project by using the following command, where the `--name` argument is the unique name of your function (`MyHttpTrigger`) and the `--template` argument specifies `HTTP trigger`.
```bash
func new --name MyHttpTrigger --template "HTTP trigger"
```
Your Azure Functions app structure might look like this:
![Azure Functions app structure in Visual Studio Code][image-01]
Run the Function app on your local by running the command below:
```bash
func host start
```
Open a web browser and type the following URL, and you will be able to see the Functions app is up and running, which returns the response.
```http
http://localhost:7071/api/MyHttpTrigger?name=OpenApi
```
![Azure Functions run result on a web browser][image-02]
## Enable Open API Metadata ##
To enable Open API metadata, you will need to install a NuGet package, [Microsoft.Azure.WebJobs.Extensions.OpenApi][az func openapi extension].
```bash
dotnet add package Microsoft.Azure.WebJobs.Extensions.OpenApi
```
With [Visual Studio Code][vs code], open your HTTP trigger, `MyHttpTrigger`, to enable the Open API metadata, and add attribute classes on top of the `FunctionName(...)` decorator.
```csharp
namespace MyOpenApiFunctionApp
{
public static class MyHttpTrigger
{
// Add these three attribute classes below
[OpenApiOperation(operationId: "getName", tags: new[] { "name" }, Summary = "Gets the name", Description = "This gets the name.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "The name", Description = "The name", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Summary = "The response", Description = "This returns the response")]
// Add these three attribute classes above
[FunctionName("MyHttpTrigger")]
public static async Task<IActionResult> Run(
...
```
Run the Function app again on your local by running the command below:
```bash
func host start
```
Open your web browser and type the following URL, and you will be able to see the Swagger UI page that describes your HTTP API endpoint above.
```http
http://localhost:7071/api/swagger/ui
```
![Swagger UI for Azure Functions app on local machine][image-03]
Copy the link in the search bar at the top of the page and open it on another web browser window, and you will be able to see the Open API 2.0 document generated on-the-fly.
![swagger.json][image-04]
## Sign-in to Azure ##
Before you can publish your app, you must sign in to Azure.
1. If you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure...**. If you don't already have one, you can [Create a free Azure account][az account free]. Students can [create a free Azure account for Students][az account free students].
![Sign in to Azure within VS Code][image-05]
If you're already signed in, go to the next section.
1. When prompted in the browser, choose your Azure account and sign in using your Azure account credentials.
1. After you've successfully signed in, you can close the new browser window. The subscriptions that belong to your Azure account are displayed in the Side bar.
## Deploy Function App to Azure ##
Once logged into Azure, create a function app and related resources in your Azure subscription and then deploy your code.
> [!IMPORTANT]
> Deploying to an existing function app overwrites the content of that app in Azure.
1. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app...** button.
![Publish your project to Azure][image-06]
1. Provide the following information at the prompts:
* **Select folder**: Choose a folder from your workspace or browse to one that contains your function app. You won't see this if you already have a valid function app opened.
* **Select subscription**: Choose the subscription to use. You won't see this if you only have one subscription.
* **Select Function App in Azure**: Choose `- Create new Function App`. (Don't choose the `Advanced` option, which isn't covered in this article.)
* **Enter a globally unique name for the function app**: Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions.
* **Select a location for new resources**: For better performance, choose a [region][az region] near you.
1. When completed, the following Azure resources are created in your subscription, using names based on your function app name:
* A resource group, which is a logical container for related resources.
* A standard Azure Storage account, which maintains state and other information about your projects.
* A consumption plan, which defines the underlying host for your serverless function app.
* A function app, which provides the environment for executing your function code. A function app lets you group functions as a logical unit for easier management, deployment, and sharing of resources within the same hosting plan.
* An Application Insights instance connected to the function app, which tracks usage of your serverless function.
A notification is displayed after your function app is created and the deployment package is applied.
1. Select **View output** in this notification to view the creation and deployment results, including the Azure resources that you created. If you miss the notification, select the bell icon in the lower right corner to see it again.
![Create complete notification][image-07]
## Run Function App in Azure ##
1. Back in the **Azure: Functions** area in the side bar, expand the new function app under your subscription. Expand **Functions**, and you will be able to see several functions including `RenderSwaggerUI`. Right-click (Windows) or <kbd>Ctrl -</kbd> click (macOS) on `RenderSwaggerUI`, and then choose **Copy Function URL**.
![Copy the function URL for the new HTTP trigger][image-08]
1. Paste this URL for the HTTP request into your browser's address bar, and execute the request. The URL that calls your HTTP-triggered function should be in the following format:
```http
http://<functionappname>.azurewebsites.net/api/swagger/ui
```
You should be able to see the same Swagger UI page as what you saw in your local machine.
![Swagger UI for Azure Functions app on Azure][image-09]
## Clean-up Resources ##
When you continue to the next step, [Integrating Open API-enabled Azure Functions with Azure API Management](integrate-with-apim.md), you'll need to keep all your resources in place to build on what you've already done.
Otherwise, you can use the following steps to delete the function app and its related resources to avoid incurring any further costs.
1. In Visual Studio Code, press <kbd>F1</kbd> to open the command palette. In the command palette, search for and select `Azure Functions: Open in portal`.
1. Choose your function app, and press <kbd>Enter</kbd>. The function app page opens in the Azure portal.
1. In the **Overview** tab, select the named link next to **Resource group**.
![Select the resource group to delete from the function app page][image-10]
1. In the **Resource group** page, review the list of included resources, and verify that they are the ones you want to delete.
1. Select **Delete resource group**, and follow the instructions.
Deletion may take a couple of minutes. When it's done, a notification appears for a few seconds. You can also select the bell icon at the top of the page to view the notification.
To learn more about Functions costs, see [Estimating Consumption plan costs][az func costs].
## Next Steps ##
You have got an Azure Functions app with Open API metadata enabled. In the next articles, you will be able to integrate this Open API-enabled Azure Functions app with either [Azure API Management][az apim], [Azure Logic Apps][az logapp] or [Power Platform][power platform].
* [Integrating Open API-enabled Azure Functions to Azure API Management][docs apim]
* [Integrating Open API-enabled Azure Functions to Power Platform][docs powerplatform]
[image-01]: images/image-01.png
[image-02]: images/image-02.png
[image-03]: images/image-03.png
[image-04]: images/image-04.png
[image-05]: images/image-05.png
[image-06]: images/image-06.png
[image-07]: images/image-07.png
[image-08]: images/image-08.png
[image-09]: images/image-09.png
[image-10]: images/image-10.png
[docs apim]: integrate-with-apim.md
[docs powerplatform]: integrate-with-powerplatform.md
[dotnet core sdk]: https://dotnet.microsoft.com/download/dotnet-core/3.1?WT.mc_id=azfuncopenapi-github-juyoo
[az account free]: https://azure.microsoft.com/free/?WT.mc_id=azfuncopenapi-github-juyoo
[az account free students]: https://azure.microsoft.com/free/students/?WT.mc_id=azfuncopenapi-github-juyoo
[az func core tools]: https://docs.microsoft.com/azure/azure-functions/functions-run-local?WT.mc_id=azfuncopenapi-github-juyoo
[az func openapi extension]: https://nuget.org/to-be-added
[az func openapi v1 preview]: https://docs.microsoft.com/azure/azure-functions/functions-api-definition?WT.mc_id=azfuncopenapi-github-juyoo
[az func openapi community]: https://github.com/aliencube/AzureFunctions.Extensions
[az func create]: https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function-azure-cli?tabs=bash%2Cbrowser&pivots=programming-language-csharp&WT.mc_id=azfuncopenapi-github-juyoo
[az func costs]: https://docs.microsoft.com/azure/azure-functions/functions-consumption-costs?WT.mc_id=azfuncopenapi-github-juyoo
[az apim]: https://docs.microsoft.com/azure/api-management/api-management-key-concepts?WT.mc_id=azfuncopenapi-github-juyoo
[az logapp]: https://docs.microsoft.com/azure/logic-apps/logic-apps-overview?WT.mc_id=azfuncopenapi-github-juyoo
[az region]: https://azure.microsoft.com/regions/?WT.mc_id=azfuncopenapi-github-juyoo
[power platform]: https://powerplatform.microsoft.com/?WT.mc_id=azfuncopenapi-github-juyoo
[openapi]: https://www.openapis.org/
[postman]: https://www.postman.com/
[vs code]: https://code.visualstudio.com/
[vs code azure tools]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-node-azure-pack

Двоичные данные
docs/images/image-01.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 65 KiB

Двоичные данные
docs/images/image-02.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 31 KiB

Двоичные данные
docs/images/image-03.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 218 KiB

Двоичные данные
docs/images/image-04.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 229 KiB

Двоичные данные
docs/images/image-05.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 70 KiB

Двоичные данные
docs/images/image-06.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 56 KiB

Двоичные данные
docs/images/image-07.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 58 KiB

Двоичные данные
docs/images/image-08.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 180 KiB

Двоичные данные
docs/images/image-09.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 246 KiB

Двоичные данные
docs/images/image-10.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 54 KiB

Просмотреть файл

@ -0,0 +1,3 @@
# Integrating Open API-enabled Azure Functions with Azure API Management #
TBD

Просмотреть файл

@ -0,0 +1,3 @@
# Integrating Open API-enabled Azure Functions with Power Platform #
TBD

Просмотреть файл

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -6,7 +6,6 @@ using System.Text;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.Extensions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.OpenApi.Models;
@ -204,12 +203,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI
this._filename = csproj.Name;
}
var fqpath =
#if NET461
System.IO.Path.IsPathRooted(path)
#else
System.IO.Path.IsPathFullyQualified(path)
#endif
var fqpath = System.IO.Path.IsPathFullyQualified(path)
? path
: $"{Environment.CurrentDirectory.TrimEnd(directorySeparator)}{directorySeparator}{path}";

Просмотреть файл

@ -1,13 +1,10 @@
#if !NET461
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
@ -35,7 +32,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocument))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderSwaggerDocument(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.{extension}")] HttpRequest req,
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "swagger.{extension}")] HttpRequest req,
string extension,
ILogger log)
{
@ -72,7 +69,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocument))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderOpenApiDocument(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/{version}.{extension}")] HttpRequest req,
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "openapi/{version}.{extension}")] HttpRequest req,
string version,
string extension,
ILogger log)
@ -108,7 +105,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerUI))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderSwaggerUI(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger/ui")] HttpRequest req,
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "swagger/ui")] HttpRequest req,
ILogger log)
{
log.LogInformation($"SwaggerUI page was requested.");
@ -131,4 +128,3 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi
}
}
}
#endif

Просмотреть файл

@ -1,326 +0,0 @@
#if NET461
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi
{
/// <summary>
/// This represents the HTTP trigger entity for Open API documents.
/// </summary>
public static class OpenApiHttpTrigger
{
private const string V2 = "v2";
private const string V3 = "v3";
private const string JSON = "json";
private const string YAML = "yaml";
private readonly static IOpenApiHttpTriggerContext context = new OpenApiHttpTriggerContext();
/// <summary>
/// Invokes the HTTP trigger endpoint to get Swagger document in a format of JSON.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Swagger document in a format of JSON.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocumentInJson))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderSwaggerDocumentInJson(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.json")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"swagger.json was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(JSON))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(JSON).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Swagger document in a format of YAML.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Swagger document in a format in YAML.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocumentInYml))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderSwaggerDocumentInYml(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.yml")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"swagger.yaml was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(YAML).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Swagger document in a format of YAML.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Swagger document in a format in YAML.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocumentInYaml))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderSwaggerDocumentInYaml(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.yaml")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"swagger.yaml was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(YAML).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Open API document v2 in a format of JSON.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Open API document v2 in a format of JSON.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV2InJson))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderOpenApiDocumentV2InJson(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v2.json")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"v2.json was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(JSON))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(JSON).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Open API document v2 in a format of YAML.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Open API document v2 in a format of YAML.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV2InYml))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderOpenApiDocumentV2InYml(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v2.yml")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"v2.yaml was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(YAML).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Open API document v2 in a format of YAML.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Open API document v2 in a format of YAML.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV2InYaml))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderOpenApiDocumentV2InYaml(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v2.yaml")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"v2.yaml was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V2), context.GetOpenApiFormat(YAML))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(YAML).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Open API document v3 in a format of JSON.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Open API document v2 in a format of JSON.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV3InJson))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderOpenApiDocumentV3InJson(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v3.json")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"v3.json was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V3), context.GetOpenApiFormat(JSON))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(JSON).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Open API document v3 in a format of YAML.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Open API document v3 in a format of YAML.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV3InYml))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderOpenApiDocumentV3InYml(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v3.yml")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"v3.yaml was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V3), context.GetOpenApiFormat(YAML))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(YAML).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to get Open API document v3 in a format of YAML.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Open API document v3 in a format of YAML.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocumentV3InYaml))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderOpenApiDocumentV3InYaml(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/v3.yaml")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"v3.yaml was requested.");
var result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.GetExecutingAssembly())
.RenderAsync(context.GetOpenApiSpecVersion(V3), context.GetOpenApiFormat(YAML))
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, context.GetOpenApiFormat(YAML).GetContentType());
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
/// <summary>
/// Invokes the HTTP trigger endpoint to render Swagger UI in HTML.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <param name="log"><see cref="ILogger"/> instance.</param>
/// <returns>Swagger UI in HTML.</returns>
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerUI))]
[OpenApiIgnore]
public static async Task<HttpResponseMessage> RenderSwaggerUI(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger/ui")] HttpRequestMessage req,
ILogger log)
{
log.LogInformation($"SwaggerUI page was requested.");
var result = await context.SwaggerUI
.AddMetadata(context.OpenApiInfo)
.AddServer(req, context.HttpSettings.RoutePrefix)
.BuildAsync()
.RenderAsync("swagger.json", context.GetSwaggerAuthKey())
.ConfigureAwait(false);
var content = new StringContent(result, Encoding.UTF8, "text/html");
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
return response;
}
}
}
#endif

Просмотреть файл

@ -1,14 +1,7 @@
#if NET461
using System.Net;
using System.Net.Http;
#endif
using System.Threading.Tasks;
#if !NET461
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
#endif
using Microsoft.Azure.WebJobs;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
{
@ -17,20 +10,6 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
/// </summary>
public class FakeHttpTrigger
{
#if NET461
/// <summary>
/// Gets something.
/// </summary>
/// <param name="req"><see cref="HttpRequestMessage"/> instance.</param>
/// <returns>Returns <see cref="HttpResponseMessage"/> instance.</returns>
[FunctionName("FakeFunction")]
public async Task<HttpResponseMessage> DoSomething(
[HttpTrigger] HttpRequestMessage req
)
{
return await Task.FromResult(req.CreateResponse(HttpStatusCode.OK)).ConfigureAwait(false);
}
#else
/// <summary>
/// Gets something
/// </summary>
@ -43,6 +22,5 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
#endif
}
}

Просмотреть файл

@ -35,7 +35,6 @@
<Compile Include="..\..\templates\OpenApiEndpints\IOpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTrigger.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTriggerV1.cs" />
</ItemGroup>
</Project>