This commit is contained in:
Justin Yoo 2020-08-25 21:26:37 +09:00 коммит произвёл GitHub
Родитель 17300c4ba2
Коммит 629de2483b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
273 изменённых файлов: 18342 добавлений и 0 удалений

425
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,425 @@
# Version: 1.3.1 (Using https://semver.org/)
# Updated: 2019-08-04
# See https://github.com/RehanSaeed/EditorConfig/releases for release notes.
# See https://github.com/RehanSaeed/EditorConfig for updates to this file.
# See http://EditorConfig.org for more information about .editorconfig files.
##########################################
# Common Settings
##########################################
# This file is the top-most EditorConfig file
root = true
# All Files
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
##########################################
# File Extension Settings
##########################################
# Visual Studio Solution Files
[*.sln]
indent_style = tab
# Visual Studio XML Project Files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
# Various XML Configuration Files
[*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}]
indent_size = 2
# JSON Files
[*.{json,json5}]
indent_size = 2
# YAML Files
[*.{yml,yaml}]
indent_size = 2
# Markdown Files
[*.md]
trim_trailing_whitespace = false
# Web Files
[*.{htm,html,js,ts,tsx,css,sass,scss,less,svg,vue}]
indent_size = 2
# Batch Files
[*.{cmd,bat}]
# Bash Files
[*.sh]
end_of_line = lf
##########################################
# .NET Language Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions
##########################################
# .NET Code Style Settings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#net-code-style-settings
[*.{cs,csx,cake,vb}]
# "this." and "Me." qualifiers
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#this-and-me
dotnet_style_qualification_for_field = true:warning
dotnet_style_qualification_for_property = true:warning
dotnet_style_qualification_for_method = true:warning
dotnet_style_qualification_for_event = true:warning
# Language keywords instead of framework type names for type references
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#language-keywords
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
# Modifier preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#normalize-modifiers
dotnet_style_require_accessibility_modifiers = always:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async
dotnet_style_readonly_field = true:warning
# Parentheses preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parentheses-preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
# Expression-level preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
dotnet_style_object_initializer = true:warning
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false:suggestion
dotnet_style_prefer_conditional_expression_over_return = false:suggestion
dotnet_style_prefer_compound_assignment = true:warning
# Null-checking preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#null-checking-preferences
dotnet_style_coalesce_expression = true:warning
dotnet_style_null_propagation = true:warning
# Parameter preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parameter-preferences
dotnet_code_quality_unused_parameters = all:warning
# More style options (Undocumented)
# https://github.com/MicrosoftDocs/visualstudio-docs/issues/3641
dotnet_style_operator_placement_when_wrapping = end_of_line
# C# Code Style Settings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-code-style-settings
[*.{cs,csx,cake}]
# Implicit and explicit types
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#implicit-and-explicit-types
csharp_style_var_for_built_in_types = true:warning
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_var_elsewhere = true:warning
# Expression-bodied members
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-bodied-members
# IDE0022
csharp_style_expression_bodied_methods = false:silent
# IDE0021
csharp_style_expression_bodied_constructors = false:silent
# IDE0023, IDE0024
csharp_style_expression_bodied_operators = false:silent
# IDE0025
csharp_style_expression_bodied_properties = true:silent
# IDE0026
csharp_style_expression_bodied_indexers = true:silent
# IDE0027
csharp_style_expression_bodied_accessors = true:silent
# IDE0053
csharp_style_expression_bodied_lambdas = true:silent
# IDE0061
csharp_style_expression_bodied_local_functions = false:silent
# Pattern matching
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#pattern-matching
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
# Inlined variable declarations
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#inlined-variable-declarations
csharp_style_inlined_variable_declaration = true:warning
# Expression-level preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
csharp_prefer_simple_default_expression = true:warning
# "Null" checking preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-null-checking-preferences
csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning
# Code block preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#code-block-preferences
csharp_prefer_braces = true:warning
# Unused value preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#unused-value-preferences
csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
# Index and range preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#index-and-range-preferences
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning
# Miscellaneous preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#miscellaneous-preferences
csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_using_directive_placement = outside_namespace:warning
csharp_prefer_static_local_function = true:warning
csharp_prefer_simple_using_statement = false:warning
##########################################
# .NET Formatting Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference#formatting-conventions
##########################################
# Organize usings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#organize-using-directives
dotnet_sort_system_directives_first = always:error
dotnet_separate_import_directive_groups = always:error
# Newline options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#new-line-options
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#indentation-options
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = no_change
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents_when_block = false
# Spacing options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#spacing-options
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_after_comma = true
csharp_space_before_comma = false
csharp_space_after_dot = false
csharp_space_before_dot = false
csharp_space_after_semicolon_in_for_statement = true
csharp_space_before_semicolon_in_for_statement = false
csharp_space_around_declaration_statements = false
csharp_space_before_open_square_brackets = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_square_brackets = false
# Wrapping options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#wrap-options
csharp_preserve_single_line_statements = false
csharp_preserve_single_line_blocks = true
##########################################
# .NET Naming Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-naming-conventions
##########################################
[*.{cs,csx,cake,vb}]
##########################################
# Styles
##########################################
# camel_case_style - Define the camelCase style
dotnet_naming_style.camel_case_style.capitalization = camel_case
# pascal_case_style - Define the PascalCase style
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# first_upper_style - The first character must start with an upper-case character
dotnet_naming_style.first_upper_style.capitalization = first_word_upper
# prefix_interface_with_i_style - Interfaces must be PascalCase and the first character of an interface must be an 'I'
dotnet_naming_style.prefix_interface_with_i_style.capitalization = pascal_case
dotnet_naming_style.prefix_interface_with_i_style.required_prefix = I
# prefix_type_parameters_with_t_style - Generic Type Parameters must be PascalCase and the first character must be a 'T'
dotnet_naming_style.prefix_type_parameters_with_t_style.capitalization = pascal_case
dotnet_naming_style.prefix_type_parameters_with_t_style.required_prefix = T
# disallowed_style - Anything that has this style applied is marked as disallowed
dotnet_naming_style.disallowed_style.capitalization = pascal_case
dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____
dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____
# internal_error_style - This style should never occur... if it does, it's indicates a bug in file or in the parser using the file
dotnet_naming_style.internal_error_style.capitalization = pascal_case
dotnet_naming_style.internal_error_style.required_prefix = ____INTERNAL_ERROR____
dotnet_naming_style.internal_error_style.required_suffix = ____INTERNAL_ERROR____
##########################################
# .NET Design Guideline Field Naming Rules
# Naming rules for fields follow the .NET Framework design guidelines
# https://docs.microsoft.com/dotnet/standard/design-guidelines/index
##########################################
# All public/protected/protected_internal constant fields must be PascalCase
# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
dotnet_naming_symbols.public_protected_constant_fields_group.applicable_accessibilities = public, protected, protected_internal
dotnet_naming_symbols.public_protected_constant_fields_group.required_modifiers = const
dotnet_naming_symbols.public_protected_constant_fields_group.applicable_kinds = field
dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.symbols = public_protected_constant_fields_group
dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.severity = warning
# All public/protected/protected_internal static readonly fields must be PascalCase
# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_accessibilities = public, protected, protected_internal
dotnet_naming_symbols.public_protected_static_readonly_fields_group.required_modifiers = static, readonly
dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_kinds = field
dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.symbols = public_protected_static_readonly_fields_group
dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.severity = warning
# No other public/protected/protected_internal fields are allowed
# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
dotnet_naming_symbols.other_public_protected_fields_group.applicable_accessibilities = public, protected, protected_internal
dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field
dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group
dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style
dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error
##########################################
# StyleCop Field Naming Rules
# Naming rules for fields follow the StyleCop analyzers
# This does not override any rules using disallowed_style above
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers
##########################################
# All constant fields must be PascalCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1303.md
dotnet_naming_symbols.stylecop_constant_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
dotnet_naming_symbols.stylecop_constant_fields_group.required_modifiers = const
dotnet_naming_symbols.stylecop_constant_fields_group.applicable_kinds = field
dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.symbols = stylecop_constant_fields_group
dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.severity = warning
# All static readonly fields must be PascalCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1311.md
dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
dotnet_naming_symbols.stylecop_static_readonly_fields_group.required_modifiers = static, readonly
dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_kinds = field
dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.symbols = stylecop_static_readonly_fields_group
dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.severity = warning
# No non-private instance fields are allowed
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1401.md
dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected
dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_kinds = field
dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.symbols = stylecop_fields_must_be_private_group
dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.style = disallowed_style
dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.severity = error
# Private fields must be camelCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1306.md
dotnet_naming_symbols.stylecop_private_fields_group.applicable_accessibilities = private
dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field
dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group
dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = camel_case_style
dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning
# Local variables must be camelCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1312.md
dotnet_naming_symbols.stylecop_local_fields_group.applicable_accessibilities = local
dotnet_naming_symbols.stylecop_local_fields_group.applicable_kinds = local
dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.symbols = stylecop_local_fields_group
dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.style = camel_case_style
dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.severity = silent
# This rule should never fire. However, it's included for at least two purposes:
# First, it helps to understand, reason about, and root-case certain types of issues, such as bugs in .editorconfig parsers.
# Second, it helps to raise immediate awareness if a new field type is added (as occurred recently in C#).
dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_accessibilities = *
dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_kinds = field
dotnet_naming_rule.sanity_check_uncovered_field_case_rule.symbols = sanity_check_uncovered_field_case_group
dotnet_naming_rule.sanity_check_uncovered_field_case_rule.style = internal_error_style
dotnet_naming_rule.sanity_check_uncovered_field_case_rule.severity = error
##########################################
# Other Naming Rules
##########################################
# All of the following must be PascalCase:
# - Namespaces
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-namespaces
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
# - Classes and Enumerations
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
# - Delegates
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces#names-of-common-types
# - Constructors, Properties, Events, Methods
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-type-members
dotnet_naming_symbols.element_group.applicable_kinds = namespace, class, enum, struct, delegate, event, method, property
dotnet_naming_rule.element_rule.symbols = element_group
dotnet_naming_rule.element_rule.style = pascal_case_style
dotnet_naming_rule.element_rule.severity = warning
# Interfaces use PascalCase and are prefixed with uppercase 'I'
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
dotnet_naming_symbols.interface_group.applicable_kinds = interface
dotnet_naming_rule.interface_rule.symbols = interface_group
dotnet_naming_rule.interface_rule.style = prefix_interface_with_i_style
dotnet_naming_rule.interface_rule.severity = warning
# Generics Type Parameters use PascalCase and are prefixed with uppercase 'T'
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
dotnet_naming_symbols.type_parameter_group.applicable_kinds = type_parameter
dotnet_naming_rule.type_parameter_rule.symbols = type_parameter_group
dotnet_naming_rule.type_parameter_rule.style = prefix_type_parameters_with_t_style
dotnet_naming_rule.type_parameter_rule.severity = warning
# Function parameters use camelCase
# https://docs.microsoft.com/dotnet/standard/design-guidelines/naming-parameters
dotnet_naming_symbols.parameters_group.applicable_kinds = parameter
dotnet_naming_rule.parameters_rule.symbols = parameters_group
dotnet_naming_rule.parameters_rule.style = camel_case_style
dotnet_naming_rule.parameters_rule.severity = warning
##########################################
# License
##########################################
# The following applies as to the .editorconfig file ONLY, and is
# included below for reference, per the requirements of the license
# corresponding to this .editorconfig file.
# See: https://github.com/RehanSaeed/EditorConfig
#
# MIT License
#
# Copyright (c) 2017-2019 Muhammad Rehan Saeed
# Copyright (c) 2019 Henry Gabryjelski
#
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
# documentation files (the "Software"), to deal in the
# Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject
# to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
##########################################

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

@ -0,0 +1,48 @@
name: Build and Test
on:
push:
branches:
- main
- dev
- feature/*
jobs:
build_and_test:
name: Build and test
strategy:
matrix:
os: [ 'windows-latest' ]
dotnet: [ '3.1.401' ]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Setup .NET SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Restore NuGet packages
shell: pwsh
run: |
dir
dotnet restore .
- name: Build solution
shell: pwsh
run: |
dir
dotnet build . -c Debug -v minimal
- name: Test solution
shell: pwsh
run: |
dir
dotnet test . -c Debug

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

@ -0,0 +1,46 @@
name: Pull Request
on:
pull_request:
branches:
- main
jobs:
build_and_test:
name: Build and test
strategy:
matrix:
os: [ 'windows-latest' ]
dotnet: [ '3.1.401' ]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Setup .NET SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Restore NuGet packages
shell: pwsh
run: |
dir
dotnet restore .
- name: Build solution
shell: pwsh
run: |
dir
dotnet build . -c Debug -v minimal
- name: Test solution
shell: pwsh
run: |
dir
dotnet test . -c Debug

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

@ -0,0 +1,179 @@
name: Release NuGet
on:
push:
branches:
- release/appsettings-*
- release/swagger-*
- release/swaggercore-*
jobs:
build_test_package_release:
name: Build, test, package and release
strategy:
matrix:
os: [ 'windows-latest' ]
dotnet: [ '3.1.401' ]
runs-on: ${{ matrix.os }}
steps:
# - name: Check event payload
# shell: pwsh
# run: |
# echo ${{ toJSON(github.event) }}
- name: Set release module and version
id: release
shell: pwsh
run: |
$branch = "${{ github.event.ref }}" -replace "refs/heads/release/", ""
$segments = $branch -split "-"
$module = $segments[0]
$version = $segments[1]
# echo "::set-env name=RELEASE_MODULE::$module"
# echo "::set-env name=RELEASE_VERSION::$version"
echo "::set-output name=module::$module"
echo "::set-output name=version::$version"
- name: Check release module and version
shell: pwsh
run: |
# echo "env: $env:RELEASE_MODULE"
# echo "env: $env:RELEASE_VERSION"
echo "output: ${{ steps.release.outputs.module }}"
echo "output: ${{ steps.release.outputs.version }}"
- name: Checkout the repository
uses: actions/checkout@v2
- name: Setup .NET SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Restore NuGet packages
shell: pwsh
run: |
dir
dotnet restore .
- name: Build solution for AppSettings
if: steps.release.outputs.module == 'appsettings'
shell: pwsh
run: |
dir
dotnet build ./src/Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal
dotnet build ./test/Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests -c Release
- name: Build solution for OpenApi Core
if: steps.release.outputs.module == 'swaggercore'
shell: pwsh
run: |
dir
dotnet build ./src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal
dotnet build ./test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests -c Release
- name: Build solution for OpenApi
if: steps.release.outputs.module == 'swagger'
shell: pwsh
run: |
dir
dotnet build ./src/Microsoft.Azure.WebJobs.Extensions.OpenApi -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal
dotnet build ./test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Tests -c Release
- name: Test solution for AppSettings
if: steps.release.outputs.module == 'appsettings'
shell: pwsh
run: |
dir
dotnet test ./test/Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests -c Release
- name: Test solution for OpenApi Core
if: steps.release.outputs.module == 'swaggercore'
shell: pwsh
run: |
dir
dotnet test ./test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests -c Release
- name: Test solution for OpenApi
if: steps.release.outputs.module == 'swagger'
shell: pwsh
run: |
dir
dotnet test ./test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Tests -c Release
- name: List Package for AppSettings
if: steps.release.outputs.module == 'appsettings'
shell: pwsh
run: |
$package = Get-ChildItem -Path ./src/*.AppSettings -Include *.nupkg -Recurse | Where-Object { $_.FullName -like "*${{ steps.release.outputs.version }}*" }
$path = $package[0].FullName
$name = $package[0].Name
echo "::set-env name=PACKAGE_PATH::$path"
echo "::set-env name=PACKAGE_NAME::$name"
- name: List Package for OpenApi Core
if: steps.release.outputs.module == 'swaggercore'
shell: pwsh
run: |
$package = Get-ChildItem -Path ./src/*.OpenApi.Core -Include *.nupkg -Recurse | Where-Object { $_.FullName -like "*${{ steps.release.outputs.version }}*" }
$path = $package[0].FullName
$name = $package[0].Name
echo "::set-env name=PACKAGE_PATH::$path"
echo "::set-env name=PACKAGE_NAME::$name"
- name: List Package for OpenApi
if: steps.release.outputs.module == 'swagger'
shell: pwsh
run: |
$package = Get-ChildItem -Path ./src/*.OpenApi -Include *.nupkg -Recurse | Where-Object { $_.FullName -like "*${{ steps.release.outputs.version }}*" }
$path = $package[0].FullName
$name = $package[0].Name
echo "::set-env name=PACKAGE_PATH::$path"
echo "::set-env name=PACKAGE_NAME::$name"
- name: Check package path and name
id: package
shell: pwsh
run: |
echo "package-path: $env:PACKAGE_PATH"
echo "package-name: $env:PACKAGE_NAME"
echo "::set-output name=path::$env:PACKAGE_PATH"
echo "::set-output name=name::$env:PACKAGE_NAME"
- name: Create Release to GitHub
id: ghrelease
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: "${{ steps.release.outputs.module }}-${{ steps.release.outputs.version }}"
release_name: Release "${{ steps.release.outputs.module }}-v${{ steps.release.outputs.version }}"
draft: false
prerelease: false
- name: Upload NuGet package to GitHub
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.ghrelease.outputs.upload_url }}
asset_path: ${{ steps.package.outputs.path }}
asset_name: ${{ steps.package.outputs.name }}
asset_content_type: application/octet-stream
- name: Release to NuGet
shell: pwsh
run: |
dotnet nuget push ${{ steps.package.outputs.path }} --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}

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

@ -0,0 +1,241 @@
name: Release CLI
on:
push:
branches:
- release/cli-*
jobs:
build_test_package:
name: Build, test and package
strategy:
matrix:
os: [ 'windows-latest' ]
node: [ 10 ]
dotnet: [ '3.1.401' ]
targetFramework: [ 'netcoreapp3.1' ]
runtime: [ 'win-x64', 'linux-x64', 'osx-x64' ]
runs-on: ${{ matrix.os }}
steps:
# - name: Check event payload
# if: steps.release.outputs.module == 'cli' && ((matrix.targetFramework == 'net461' && matrix.runtime == 'win-x64') || matrix.targetFramework == 'netcoreapp3.1')
# shell: pwsh
# run: |
# echo ${{ toJSON(github.event) }}
- name: Set release module and version
id: release
shell: pwsh
run: |
$branch = "${{ github.event.ref }}" -replace "refs/heads/release/", ""
$segments = $branch -split "-"
$module = $segments[0]
$version = $segments[1]
# echo "::set-env name=RELEASE_MODULE::$module"
# echo "::set-env name=RELEASE_VERSION::$version"
echo "::set-output name=module::$module"
echo "::set-output name=version::$version"
- name: Check release module and version
if: steps.release.outputs.module == 'cli'
shell: pwsh
run: |
# echo "env: $env:RELEASE_MODULE"
# echo "env: $env:RELEASE_VERSION"
echo "output: ${{ steps.release.outputs.module }}"
echo "output: ${{ steps.release.outputs.version }}"
- name: Checkout the repository
if: steps.release.outputs.module == 'cli'
uses: actions/checkout@v2
# - name: Setup node.js
# if: steps.release.outputs.module == 'cli'
# uses: actions/setup-node@v1
# with:
# node-version: ${{ matrix.node }}
- name: Setup .NET SDK
if: steps.release.outputs.module == 'cli'
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ matrix.dotnet }}
- 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'
shell: pwsh
run: |
dir
dotnet restore .
- name: Build solution
if: steps.release.outputs.module == 'cli'
shell: pwsh
run: |
dir
dotnet build . -c Release -p:Version=${{ steps.release.outputs.version }} -v minimal
- name: Test solution
if: steps.release.outputs.module == 'cli'
shell: pwsh
run: |
dir
dotnet test . -c Release
- name: Publish CLI for .NET Core
if: steps.release.outputs.module == 'cli'
shell: pwsh
run: |
dir
dotnet publish ./src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI -c Release -f ${{ matrix.targetFramework }} -r ${{ matrix.runtime }} -p:PublishSingleFile=true --self-contained true
- name: List Package for OpenApi.CLI
if: steps.release.outputs.module == 'cli'
shell: pwsh
run: |
$sourcepath = "./src/*.OpenApi.CLI/bin/Release/${{ matrix.targetFramework }}/${{ matrix.runtime }}/publish"
$targetpath = "./src/*.OpenApi.CLI/bin/Release/${{ matrix.targetFramework }}/azfuncopenapi-v${{ steps.release.outputs.version }}-${{ matrix.targetFramework }}-${{ matrix.runtime }}.zip"
$package = Get-ChildItem -Path $sourcepath -Recurse | Compress-Archive -DestinationPath $targetpath
$path = (Get-Item $targetpath).FullName
$name = (Get-Item $targetpath).Name
echo "::set-env name=PACKAGE_PATH::$path"
echo "::set-env name=PACKAGE_NAME::$name"
- name: Check package path and name
if: steps.release.outputs.module == 'cli'
id: package
shell: pwsh
run: |
echo "package-path: $env:PACKAGE_PATH"
echo "package-name: $env:PACKAGE_NAME"
echo "::set-output name=path::$env:PACKAGE_PATH"
echo "::set-output name=name::$env:PACKAGE_NAME"
- name: Upload artifacts
if: steps.release.outputs.module == 'cli'
uses: actions/upload-artifact@v2
with:
name: cli
path: "${{ steps.package.outputs.path }}"
package_release:
name: Release packages
needs: build_test_package
strategy:
matrix:
os: [ 'ubuntu-latest' ]
node: [ 10 ]
dotnet: [ '3.1.401' ]
# targetFramework: [ 'net461', 'netcoreapp3.1' ]
# runtime: [ 'win-x64', 'linux-x64', 'osx-x64' ]
runs-on: ${{ matrix.os }}
steps:
- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: cli
path: artifacts
- name: Get all artifacts
id: package
shell: pwsh
run: |
dir ./artifacts
$packages = Get-ChildItem -Path ./artifacts
$package0 = $packages[0].Name
$package1 = $packages[1].Name
$package2 = $packages[2].Name
$package3 = $packages[3].Name
$version = $packages[0].Name.Split('-')[1].Replace("v", "")
echo "version: $version"
echo "package0: $package0"
echo "package1: $package1"
echo "package2: $package2"
echo "package3: $package3"
echo "::set-output name=version::$version"
echo "::set-output name=package0::$package0"
echo "::set-output name=package1::$package1"
echo "::set-output name=package2::$package2"
echo "::set-output name=package3::$package3"
- name: Repackage CLI for Linux and MacOS
shell: bash
run: |
unzip "./artifacts/${{ steps.package.outputs.package1 }}" -d "./artifacts/linux"
chmod +x ./artifacts/linux/azfuncopenapi
ls -al ./artifacts/linux
rm "./artifacts/${{ steps.package.outputs.package1 }}"
zip -r -j "./artifacts/${{ steps.package.outputs.package1 }}" "./artifacts/linux"
unzip "./artifacts/${{ steps.package.outputs.package2 }}" -d "./artifacts/osx"
chmod +x ./artifacts/osx/azfuncopenapi
ls -al ./artifacts/osx
rm "./artifacts/${{ steps.package.outputs.package2 }}"
zip -r -j "./artifacts/${{ steps.package.outputs.package2 }}" "./artifacts/osx"
ls -al ./artifacts
- name: Create Release to GitHub
id: ghrelease
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: "cli-${{ steps.package.outputs.version }}"
release_name: Release "cli-v${{ steps.package.outputs.version }}"
draft: false
prerelease: false
- name: Upload CLI to GitHub - netcoreapp3.1 linux-x64
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.ghrelease.outputs.upload_url }}
asset_path: "artifacts/${{ steps.package.outputs.package1 }}"
asset_name: ${{ steps.package.outputs.package1 }}
asset_content_type: application/zip
- name: Upload CLI to GitHub - netcoreapp3.1 osx-x64
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.ghrelease.outputs.upload_url }}
asset_path: "artifacts/${{ steps.package.outputs.package2 }}"
asset_name: ${{ steps.package.outputs.package2 }}
asset_content_type: application/zip
- name: Upload CLI to GitHub - netcoreapp3.1 win-x64
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.ghrelease.outputs.upload_url }}
asset_path: "artifacts/${{ steps.package.outputs.package3 }}"
asset_name: ${{ steps.package.outputs.package3 }}
asset_content_type: application/zip
# - name: Release to npm
# uses: JS-DevTools/npm-publish@v1
# with:
# token: ${{ secrets.NPM_TOKEN }}
# package: "./src/*.OpenApi.CLI/package.json"

292
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,292 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
*.bak
*.org
outputs/

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

@ -0,0 +1,160 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30128.74
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A1CB6B0E-9E97-4823-910B-735DB69B1931}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitignore = .gitignore
LICENSE = LICENSE
README.md = README.md
Settings.StyleCop = Settings.StyleCop
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{810145E0-41CF-4E24-BD9C-E7517498BA29}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings", "src\Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings\Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.csproj", "{64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.Core", "src\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.csproj", "{B18937F6-B39F-46BB-BB3C-86C0693993EF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi", "src\Microsoft.Azure.WebJobs.Extensions.OpenApi\Microsoft.Azure.WebJobs.Extensions.OpenApi.csproj", "{D405655F-C8BE-4134-893C-ADB4918B0624}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI", "src\Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI\Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.csproj", "{7AD094AA-01D6-4644-B9B6-E555A029D6D7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{66D8DEA8-B477-497F-95BB-E8F9A5BAC352}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models", "samples\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.csproj", "{6ABA1666-BC42-487F-B156-3DC79347BD6B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services", "samples\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services.csproj", "{B7CF1C77-FE6F-4586-93FE-801671A5EAFD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2Static", "samples\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2Static\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2Static.csproj", "{848EDB8F-9C45-462B-A544-EA237774F3BA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2IoC", "samples\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2IoC\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2IoC.csproj", "{D6C3806E-2685-4E8D-9F4F-7A93E5270891}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static", "samples\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static.csproj", "{C2996131-C3CA-4D3D-8357-C533849792E1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC", "samples\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC.csproj", "{8460A7F9-FED4-4495-A595-8C585FC7F606}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8B62E3FB-9062-4716-803A-1FA51FCE68BC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests.Fakes", "test\Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests.Fakes\Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests.Fakes.csproj", "{AC89B7CF-0FA5-49EE-97A8-AB39A5F211A8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests", "test\Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests\Microsoft.Azure.WebJobs.Extensions.OpenApi.AppSettings.Tests.csproj", "{AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes", "test\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes.csproj", "{1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests", "test\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.csproj", "{968CD847-80D0-4740-92D5-F5553461EC04}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.Tests", "test\Microsoft.Azure.WebJobs.Extensions.OpenApi.Tests\Microsoft.Azure.WebJobs.Extensions.OpenApi.Tests.csproj", "{D787694D-B87B-4E11-9455-B5BF9306D8FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests", "test\Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests\Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests.csproj", "{65AED6F0-D27E-4D6E-BA42-AD6EE1338082}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{56A43630-87E6-4E94-B24A-859258202578}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OpenApiEndpoints", "OpenApiEndpoints", "{41695443-A292-4909-89A6-2D9846753164}"
ProjectSection(SolutionItems) = preProject
templates\OpenApiEndpints\IOpenApiHttpTriggerContext.cs = templates\OpenApiEndpints\IOpenApiHttpTriggerContext.cs
templates\OpenApiEndpints\OpenApiHttpTrigger.cs = templates\OpenApiEndpints\OpenApiHttpTrigger.cs
templates\OpenApiEndpints\OpenApiHttpTriggerContext.cs = templates\OpenApiEndpints\OpenApiHttpTriggerContext.cs
templates\OpenApiEndpints\OpenApiHttpTriggerV1.cs = templates\OpenApiEndpints\OpenApiHttpTriggerV1.cs
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500}.Release|Any CPU.Build.0 = Release|Any CPU
{B18937F6-B39F-46BB-BB3C-86C0693993EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B18937F6-B39F-46BB-BB3C-86C0693993EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B18937F6-B39F-46BB-BB3C-86C0693993EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B18937F6-B39F-46BB-BB3C-86C0693993EF}.Release|Any CPU.Build.0 = Release|Any CPU
{D405655F-C8BE-4134-893C-ADB4918B0624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D405655F-C8BE-4134-893C-ADB4918B0624}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D405655F-C8BE-4134-893C-ADB4918B0624}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D405655F-C8BE-4134-893C-ADB4918B0624}.Release|Any CPU.Build.0 = Release|Any CPU
{7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AD094AA-01D6-4644-B9B6-E555A029D6D7}.Release|Any CPU.Build.0 = Release|Any CPU
{6ABA1666-BC42-487F-B156-3DC79347BD6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6ABA1666-BC42-487F-B156-3DC79347BD6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6ABA1666-BC42-487F-B156-3DC79347BD6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6ABA1666-BC42-487F-B156-3DC79347BD6B}.Release|Any CPU.Build.0 = Release|Any CPU
{B7CF1C77-FE6F-4586-93FE-801671A5EAFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7CF1C77-FE6F-4586-93FE-801671A5EAFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7CF1C77-FE6F-4586-93FE-801671A5EAFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7CF1C77-FE6F-4586-93FE-801671A5EAFD}.Release|Any CPU.Build.0 = Release|Any CPU
{848EDB8F-9C45-462B-A544-EA237774F3BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{848EDB8F-9C45-462B-A544-EA237774F3BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{848EDB8F-9C45-462B-A544-EA237774F3BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{848EDB8F-9C45-462B-A544-EA237774F3BA}.Release|Any CPU.Build.0 = Release|Any CPU
{D6C3806E-2685-4E8D-9F4F-7A93E5270891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6C3806E-2685-4E8D-9F4F-7A93E5270891}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6C3806E-2685-4E8D-9F4F-7A93E5270891}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6C3806E-2685-4E8D-9F4F-7A93E5270891}.Release|Any CPU.Build.0 = Release|Any CPU
{C2996131-C3CA-4D3D-8357-C533849792E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2996131-C3CA-4D3D-8357-C533849792E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2996131-C3CA-4D3D-8357-C533849792E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2996131-C3CA-4D3D-8357-C533849792E1}.Release|Any CPU.Build.0 = Release|Any CPU
{8460A7F9-FED4-4495-A595-8C585FC7F606}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8460A7F9-FED4-4495-A595-8C585FC7F606}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8460A7F9-FED4-4495-A595-8C585FC7F606}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8460A7F9-FED4-4495-A595-8C585FC7F606}.Release|Any CPU.Build.0 = Release|Any CPU
{AC89B7CF-0FA5-49EE-97A8-AB39A5F211A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC89B7CF-0FA5-49EE-97A8-AB39A5F211A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC89B7CF-0FA5-49EE-97A8-AB39A5F211A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC89B7CF-0FA5-49EE-97A8-AB39A5F211A8}.Release|Any CPU.Build.0 = Release|Any CPU
{AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8}.Release|Any CPU.Build.0 = Release|Any CPU
{1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6}.Release|Any CPU.Build.0 = Release|Any CPU
{968CD847-80D0-4740-92D5-F5553461EC04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{968CD847-80D0-4740-92D5-F5553461EC04}.Debug|Any CPU.Build.0 = Debug|Any CPU
{968CD847-80D0-4740-92D5-F5553461EC04}.Release|Any CPU.ActiveCfg = Release|Any CPU
{968CD847-80D0-4740-92D5-F5553461EC04}.Release|Any CPU.Build.0 = Release|Any CPU
{D787694D-B87B-4E11-9455-B5BF9306D8FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D787694D-B87B-4E11-9455-B5BF9306D8FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D787694D-B87B-4E11-9455-B5BF9306D8FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D787694D-B87B-4E11-9455-B5BF9306D8FC}.Release|Any CPU.Build.0 = Release|Any CPU
{65AED6F0-D27E-4D6E-BA42-AD6EE1338082}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65AED6F0-D27E-4D6E-BA42-AD6EE1338082}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65AED6F0-D27E-4D6E-BA42-AD6EE1338082}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65AED6F0-D27E-4D6E-BA42-AD6EE1338082}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{64A22A3C-D0C4-4DE9-A8D5-2CEF766EB500} = {810145E0-41CF-4E24-BD9C-E7517498BA29}
{B18937F6-B39F-46BB-BB3C-86C0693993EF} = {810145E0-41CF-4E24-BD9C-E7517498BA29}
{D405655F-C8BE-4134-893C-ADB4918B0624} = {810145E0-41CF-4E24-BD9C-E7517498BA29}
{7AD094AA-01D6-4644-B9B6-E555A029D6D7} = {810145E0-41CF-4E24-BD9C-E7517498BA29}
{66D8DEA8-B477-497F-95BB-E8F9A5BAC352} = {810145E0-41CF-4E24-BD9C-E7517498BA29}
{6ABA1666-BC42-487F-B156-3DC79347BD6B} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352}
{B7CF1C77-FE6F-4586-93FE-801671A5EAFD} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352}
{848EDB8F-9C45-462B-A544-EA237774F3BA} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352}
{D6C3806E-2685-4E8D-9F4F-7A93E5270891} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352}
{C2996131-C3CA-4D3D-8357-C533849792E1} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352}
{8460A7F9-FED4-4495-A595-8C585FC7F606} = {66D8DEA8-B477-497F-95BB-E8F9A5BAC352}
{AC89B7CF-0FA5-49EE-97A8-AB39A5F211A8} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC}
{AEF35BD6-EA9A-4159-86F4-49AF7D17A9A8} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC}
{1D1A5ED5-A1A1-4082-ACAF-30079AF31AC6} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC}
{968CD847-80D0-4740-92D5-F5553461EC04} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC}
{D787694D-B87B-4E11-9455-B5BF9306D8FC} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC}
{65AED6F0-D27E-4D6E-BA42-AD6EE1338082} = {8B62E3FB-9062-4716-803A-1FA51FCE68BC}
{41695443-A292-4909-89A6-2D9846753164} = {56A43630-87E6-4E94-B24A-859258202578}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {70FEC644-BB3C-4441-AF91-DC694803C8F2}
EndGlobalSection
EndGlobal

66
Settings.StyleCop Normal file
Просмотреть файл

@ -0,0 +1,66 @@
<StyleCopSettings Version="105">
<GlobalSettings>
<CollectionProperty Name="RecognizedWords">
<Value>dev</Value>
<Value>enums</Value>
<Value>github</Value>
<Value>json</Value>
<Value>queryable</Value>
<Value>querystring</Value>
</CollectionProperty>
<StringProperty Name="Culture">en-GB</StringProperty>
</GlobalSettings>
<Analyzers>
<Analyzer AnalyzerId="StyleCop.CSharp.ReadabilityRules">
<Rules>
<Rule Name="PrefixLocalCallsWithThis">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="PrefixCallsCorrectly">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings />
</Analyzer>
<Analyzer AnalyzerId="StyleCop.CSharp.OrderingRules">
<Rules>
<Rule Name="UsingDirectivesMustBePlacedWithinNamespace">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings />
</Analyzer>
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
<Rules>
<Rule Name="FileMustHaveHeader">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings>
<BooleanProperty Name="IgnorePrivates">True</BooleanProperty>
</AnalyzerSettings>
</Analyzer>
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
<Rules>
<Rule Name="FieldNamesMustNotBeginWithUnderscore">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings>
<CollectionProperty Name="Hungarian">
<Value>db</Value>
</CollectionProperty>
</AnalyzerSettings>
</Analyzer>
</Analyzers>
</StyleCopSettings>

13
docs/README.md Normal file
Просмотреть файл

@ -0,0 +1,13 @@
# AzureFunctions.Extensions #
This provides some useful extensions for Azure Functions.
## Getting Started ![Build and Test](https://github.com/Azure/azure-functions-openapi-extension/workflows/Build%20and%20Test/badge.svg) ##
| Package | Status | Version |
| --- | --- | --- |
| [Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings](app-settings.md) | [![](https://img.shields.io/nuget/dt/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings/) | [![](https://img.shields.io/nuget/v/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings/) |
| [Microsoft.Azure.WebJobs.Extensions.OpenApi.Core](openapi-core.md) | [![](https://img.shields.io/nuget/dt/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/) | [![](https://img.shields.io/nuget/v/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/) |
| [Microsoft.Azure.WebJobs.Extensions.OpenApi](openapi.md) | [![](https://img.shields.io/nuget/dt/Microsoft.Azure.WebJobs.Extensions.OpenApi.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/) | [![](https://img.shields.io/nuget/v/Microsoft.Azure.WebJobs.Extensions.OpenApi.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/) |
| [Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI](openapi-cli.md) | [![](https://img.shields.io/static/v1?label=tag&message=cli-*&color=brightgreen)](https://github.com/Azure/azure-functions-openapi-extension/releases) | [![](https://img.shields.io/static/v1?label=tag&message=cli-*&color=brightgreen)](https://github.com/Azure/azure-functions-openapi-extension/releases) |

17
docs/app-settings.md Normal file
Просмотреть файл

@ -0,0 +1,17 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi.Extensions.Configuration.AppSettings #
![Build and Test](https://github.com/Azure/azure-functions-openapi-extension/workflows/Build%20and%20Test/badge.svg) [![](https://img.shields.io/nuget/dt/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings/) [![](https://img.shields.io/nuget/v/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings/)
This is a base app settings environment variables deserialised. This MUST be inherited for use.
```csharp
public abstract class OpenApiAppSettingsBase : AppSettingsBase
{
public OpenApiAppSettingsBase()
: base()
{
...
}
...
}
```

73
docs/openapi-cli.md Normal file
Просмотреть файл

@ -0,0 +1,73 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI #
![Build and Test](https://github.com/Azure/azure-functions-openapi-extension/workflows/Build%20and%20Test/badge.svg) [![](https://img.shields.io/static/v1?label=tag&message=cli-*&color=brightgreen)](https://github.com/Azure/azure-functions-openapi-extension/releases) [![](https://img.shields.io/static/v1?label=tag&message=cli-*&color=brightgreen)](https://github.com/Azure/azure-functions-openapi-extension/releases)
This generates Open API document through command-line without having to run the Azure Functions instance. The more details around this CLI can be found on this [blog post](https://devkimchi.com/2020/07/08/generating-open-api-doc-for-azure-functions-in-command-line/).
> **NOTE**: This CLI supports both [Open API 2.0 (aka Swagger)](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) and [Open API 3.0.1](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md) spec.
## Issues? ##
While using this CLI, if you find any issue, please raise a ticket on the [Issue](https://github.com/Azure/azure-functions-openapi-extension/issues) page.
## Getting Started ##
### Download CLI ###
The CLI is available for download at [GitHub](https://github.com/Azure/azure-functions-openapi-extension/releases). It's always tagged with `cli-<version>`. Download the latest version of CLI.
* Linux: `azfuncopenapi-v<version>-netcoreapp3.1-linux-x64.zip`
* MacOS: `azfuncopenapi-v<version>-netcoreapp3.1-osx-x64.zip`
* Windows: `azfuncopenapi-v<version>-netcoreapp3.1-win-x64.zip`
### Generating Open API Document ###
Once you have an Azure Functions instance with [Azure Functions Open API extension](openapi.md) enabled, then you are ready to run this CLI.
For Windows:
```powershell
# PowerShell Console
azfuncopenapi `
--project <PROJECT_PATH> `
--configuration Debug `
--target netcoreapp2.1 `
--version v2 `
--format json `
--output output `
--console false
```
For Linux/MacOS
```bash
# Bash
./azfuncopenapi \
--project <PROJECT_PATH> \
--configuration Debug \
--target netcoreapp2.1 \
--version v2 \
--format json \
--output output \
--console false
```
Here are options:
* `-p|--project`: Project path. It can be a fully qualified project path including `.csproj` or project directory. Default is the current directory.
* `-c|--configuration`: Configuration value. It can be either `Debug`, `Release` or something else. Default is `Debug`.
* `-t|--target`: Target framework. It should be `netcoreapp2.x` for Azure Functions v2, and `netcoreapp3.x` for Azure Functions v3. Default is `netcoreapp2.1`.
* `-v|--version`: Open API spec version. It should be either `v2` or `v3`. Default is `v2`.
* `-f|--format`: Open API document format. It should be either `json` or `yaml`. Default is `json`.
* `-o|--output`: Output directory for the generated Open API document. It can be a fully qualified directory path or relative path from `<PROJECT_ROOT>/bin/<CONFIGURATION>/<TARGET_FRAMEWORK>`. Default is `output`.
* `--console`: Value indicating whether to display the generated document to console or not. Default is `false`.
## Roadmap ##
* Distribution through a npm package.
* Project boilerplate generation, if an Open API doc is provided.

308
docs/openapi-core.md Normal file
Просмотреть файл

@ -0,0 +1,308 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi.Core #
![Build and Test](https://github.com/Azure/azure-functions-openapi-extension/workflows/Build%20and%20Test/badge.svg) [![](https://img.shields.io/nuget/dt/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/) [![](https://img.shields.io/nuget/v/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/)
This enables Azure Functions to render Open API document and Swagger UI. The more details around the Swagger UI on Azure Functions can be found on this [blog post](https://devkimchi.com/2019/02/02/introducing-swagger-ui-on-azure-functions/).
> **NOTE**: This extension supports both [Open API 2.0 (aka Swagger)](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) and [Open API 3.0.1](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md) spec.
## 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).
## Issues? ##
While using this library, if you find any issue, please raise a ticket on the [Issue](https://github.com/Azure/azure-functions-openapi-extension/issues) page.
## Getting Started ##
### Install NuGet Package ###
In order for your Azure Functions app to enable Open API capability, download the following NuGet package into your Azure Functions project.
```bash
dotnet add <PROJECT> package Microsoft.Azure.WebJobs.Extensions.OpenApi.OpenApi.Core
```
### Expose Endpoints to Open API Document ###
In order to include HTTP endpoints into the Open API document, use attribute classes (decorators) like:
```csharp
[FunctionName(nameof(AddDummy))]
[OpenApiOperation("addDummy", "dummy")]
[OpenApiRequestBody("application/json", typeof(DummyRequestModel))]
[OpenApiResponseBody(HttpStatusCode.OK, "application/json", typeof(DummyResponseModel))]
public static async Task<IActionResult> AddDummy(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "dummies")] HttpRequest req,
ILogger log)
{
...
}
```
### Configure App Settings Key ###
This key is only required if:
* The Function app is deployed to Azure, and
* The Open API related endpoints has the `AuthorizationLevel` value other than `Anonymous`.
If the above conditions are met, add the following key to your `local.settings.json` or App Settings blade on Azure.
* `OpenApi__ApiKey`: either the host key value or the master key value.
> **NOTE**: It is NOT required if your Open API related endpoints are set to the authorisation level of `Anonymous`.
## Open API Metadata Configuration ##
To generate an Open API document, [OpenApiInfo object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#infoObject) needs to be defined. This information can be declared in **ONE OF THREE** places &ndash; `host.json`, `openapisettings.json` or `local.settings.json`.
This library looks for the information in the following order:
1. `host.json`
2. `openapisettings.json`
3. `local.settings.json` or App Settings blade on Azure
### `host.json` ###
Although it has not been officially accepted to be a part of `host.json`, the Open API metadata still can be stored in it like:
```json
{
...
"openApi": {
"info": {
"version": "1.0.0",
"title": "Open API Sample on Azure Functions",
"description": "A sample API that runs on Azure Functions 3.x using Open API specification - from **host. json**.",
"termsOfService": "https://github.com/Azure/azure-functions-openapi-extension",
"contact": {
"name": "Azure Functions Open API",
"email": "azfunc-openapi@microsoft.com",
"url": "https://github.com/Azure/azure-functions-openapi-extension/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}
...
}
```
### `openapisettings.json` ###
The Open API metadata can be defined in a separate file, `openapisettings.json` like:
```json
{
"info": {
"version": "1.0.0",
"title": "Open API Sample on Azure Functions",
"description": "A sample API that runs on Azure Functions 3.x using Open API specification - from **openapisettings.json**.",
"termsOfService": "https://github.com/Azure/azure-functions-openapi-extension",
"contact": {
"name": "Azure Functions Open API",
"email": "azfunc-openapi@microsoft.com",
"url": "https://github.com/Azure/azure-functions-openapi-extension/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}
```
### `local.settings.json` or App Settings Blade ###
On either your `local.settings.json` or App Settings on Azure Functions instance, those details can be set up like:
* `OpenApi__Info__Version`: **REQUIRED** Version of Open API document. This is not the version of Open API spec. eg. 1.0.0
* `OpenApi__Info__Title`: **REQUIRED** Title of Open API document. eg. Open API Sample on Azure Functions
* `OpenApi__Info__Description`: Description of Open API document. eg. A sample API that runs on Azure Functions either 1.x or 2.x using Open API specification.
* `OpenApi__Info__TermsOfService`: Terms of service URL. eg. https://github.com/aliencube/AzureFunctions.Extensions
* `OpenApi__Info__Contact__Name`: Name of contact. eg. Aliencube Community
* `OpenApi__Info__Contact__Email`: Email address for the contact. eg. no-reply@aliencube.org
* `OpenApi__Info__Contact__Url`: Contact URL. eg. https://github.com/aliencube/AzureFunctions.Extensions/issues
* `OpenApi__Info__License__Name`: **REQUIRED** License name. eg. MIT
* `OpenApi__Info__License__Url`: License URL. eg. http://opensource.org/licenses/MIT
> **NOTE**: In order to deploy Azure Functions v1 to Azure, the `AzureWebJobsScriptRoot` **MUST** be specified in the app settings section; otherwise it will throw an error that can't find `host.json`. Local debugging is fine, though. For more details, please visit [this page](https://docs.microsoft.com/azure/azure-functions/functions-app-settings#azurewebjobsscriptroot?WT.mc_id=azfuncextension-github-juyoo).
## Decorators ##
In order to render Open API document, this uses attribute classes (decorators).
> **NOTE**: Not all Open API specs have been implemented.
### `OpenApiIgnoreAttribute` ###
If there is any HTTP trigger that you want to exclude from the Open API document, use this decorator. Typically this is used for the endpoints that render Open API document and Swagger UI.
```csharp
[FunctionName(nameof(RenderSwaggerDocument))]
[OpenApiIgnore] // This HTTP endpoint is excluded from the Open API document.
public static async Task<IActionResult> RenderSwaggerDocument(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger.{extension}")] HttpRequest req,
string extension,
ILogger log)
{
...
}
```
### `OpenApiOperationAttribute` ###
This decorator implements a part of [Operation object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#operationObject) spec.
```csharp
[FunctionName(nameof(GetSample))]
[OpenApiOperation(operationId: "list", tags: new[] { "sample" })]
...
public static async Task<IActionResult> GetSample(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "samples")] HttpRequest req,
ILogger log)
{
...
}
```
* `OperationId`: is the ID of the operation. If this is omitted, a combination of function name and verb is considered as the operation ID. eg) `Get_GetSample`
* `Tags`: are the list of tags of operation.
* `Summary`: is the summary of the operation.
* `Description`: is the description of the operation.
* `Visibility`: indicates how the operation is visible in Azure Logic Apps &ndash; `important`, `advanced` or `internal`. Default value is `undefined`.
### `OpenApiParameterAttribute` ###
This decorator implements the [Parameter object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#parameterObject) spec.
```csharp
[FunctionName(nameof(GetSample))]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string))]
...
public static async Task<IActionResult> GetSample(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "samples")] HttpRequest req,
ILogger log)
{
...
}
```
* `Name`: is the name of the parameter.
* `Summary`: is the summary of the parameter.
* `Description`: is the description of the parameter.
* `Type`: defines the parameter type. Default value is `typeof(string)`.
* `In`: identifies where the parameter is located &ndash; `header`, `path`, `query` or `cookie`. Default value is `path`.
* `CollectionDelimiter`: identifies the delimiter when a query parameter accepts multiple values &ndash; `comma`, `space` or `pipe`. Default value is `comma`.
* `Explode`: indicates whether a query parameter is used multiple times (eg. `foo=bar1&foo=bar2&foo=bar3`) or not (eg. `foo=bar1,bar2,bar3`). Default value is `false`.
* `Required`: indicates whether the parameter is required or not. Default value is `false`.
* `Visibility`: indicates how the parameter is visible in Azure Logic Apps &ndash; `important`, `advanced` or `internal`. Default value is `undefined`.
### `OpenApiRequestBodyAttribute` ###
This decorator implements the [Request Body object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#requestBodyObject) spec.
```csharp
[FunctionName(nameof(PostSample))]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(SampleRequestModel))]
...
public static async Task<IActionResult> PostSample(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "samples")] HttpRequest req,
ILogger log)
{
...
}
```
* `ContentType`: defines the content type of the request body payload. eg) `application/json` or `text/xml`
* `BodyType`: defines the type of the request payload.
* `Summary`: is the summary of the request payload.
* `Description`: is the description of the request payload.
* `Required`: indicates whether the request payload is mandatory or not.
### `OpenApiResponseWithBodyAttribute` ###
This decorator implements the [Response object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#responseObject) spec.
```csharp
[FunctionName(nameof(PostSample))]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(SampleResponseModel))]
...
public static async Task<IActionResult> PostSample(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "samples")] HttpRequest req,
ILogger log)
{
...
}
```
* `StatusCode`: defines the HTTP status code. eg) `HttpStatusCode.OK`
* `ContentType`: defines the content type of the response payload. eg) `application/json` or `text/xml`
* `BodyType`: defines the type of the response payload.
* `Summary`: is the summary of the response.
* `Description`: is the description of the response.
### `OpenApiResponseWithoutBodyAttribute` ###
This decorator implements the [Response object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#responseObject) spec.
```csharp
[FunctionName(nameof(PostSample))]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.OK)]
...
public static async Task<IActionResult> PostSample(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "samples")] HttpRequest req,
ILogger log)
{
...
}
```
* `StatusCode`: defines the HTTP status code. eg) `HttpStatusCode.OK`
* `Summary`: is the summary of the response.
* `Description`: is the description of the response.
## Supported Json.NET Decorators ##
Those attribute classes from [Json.NET](https://www.newtonsoft.com/json) are supported for payload definitions.
### `JsonIgnore` ###
Properties decorated with the `JsonIgnore` attribute class will not be included in the response.
### `JsonProperty` ###
Properties decorated with `JsonProperty` attribute class will use `JsonProperty.Name` value instead of their property names. In addition to this, if `JsonProperty.Required` property has `Required.Always` or `Required.DisallowNull`, the property will be recognised as the `required` field.
### `JsonRequired` ###
Properties decorated with `JsonRequired` attribute class will be recognised as the `required` field.
### `JsonConverter` ###
Enums types decorated with `[JsonConverter(typeof(StringEnumConverter))]` will appear in the document with their string names (names mangled based on default property naming standard).

195
docs/openapi.md Normal file
Просмотреть файл

@ -0,0 +1,195 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi #
![Build and Test](https://github.com/Azure/azure-functions-openapi-extension/workflows/Build%20and%20Test/badge.svg) [![](https://img.shields.io/nuget/dt/Microsoft.Azure.WebJobs.Extensions.OpenApi.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/) [![](https://img.shields.io/nuget/v/Microsoft.Azure.WebJobs.Extensions.OpenApi.svg)](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/)
This enables Azure Functions to render Open API document and Swagger UI. The more details around the Swagger UI on Azure Functions can be found on this [blog post](https://devkimchi.com/2019/02/02/introducing-swagger-ui-on-azure-functions/).
> **NOTE**: This extension supports both [Open API 2.0 (aka Swagger)](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) and [Open API 3.0.1](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md) spec.
## 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).
## Issues? ##
While using this library, if you find any issue, please raise a ticket on the [Issue](https://github.com/Azure/azure-functions-openapi-extension/issues) page.
## Getting Started ##
### Install NuGet Package ###
In order for your Azure Functions app to enable Open API capability, download the following NuGet package into your Azure Functions project.
```bash
dotnet add <PROJECT> package Microsoft.Azure.WebJobs.Extensions.OpenApi
```
### Change Authorization Level ###
As a default, all endpoints to render Swagger UI and Open API documents have the authorisation level of `AuthorizationLevel.Function`, which requires the API key to render them.
```csharp
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocument))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderSwaggerDocument(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger.{extension}")] HttpRequest req,
string extension,
ILogger log)
{
...
}
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocument))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderOpenApiDocument(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "openapi/{version}.{extension}")] HttpRequest req,
string version,
string extension,
ILogger log)
{
...
}
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerUI))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderSwaggerUI(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "swagger/ui")] HttpRequest req,
ILogger log)
{
...
}
```
However, if you don't want to use the API key for them, change their authorisation level to `AuthorizationLevel.Anonymous`.
```csharp
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerDocument))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderSwaggerDocument(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "swagger.{extension}")] HttpRequest req,
string extension,
ILogger log)
{
...
}
[FunctionName(nameof(OpenApiHttpTrigger.RenderOpenApiDocument))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderOpenApiDocument(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "openapi/{version}.{extension}")] HttpRequest req,
string version,
string extension,
ILogger log)
{
...
}
[FunctionName(nameof(OpenApiHttpTrigger.RenderSwaggerUI))]
[OpenApiIgnore]
public static async Task<IActionResult> RenderSwaggerUI(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "swagger/ui")] HttpRequest req,
ILogger log)
{
...
}
```
### Configure App Settings Key ###
This key is only required if:
* The Function app is deployed to Azure, and
* The Open API related endpoints has the `AuthorizationLevel` value other than `Anonymous`.
If the above conditions are met, add the following key to your `local.settings.json` or App Settings blade on Azure.
* `OpenApi__ApiKey`: either the host key value or the master key value.
> **NOTE**: It is NOT required if your Open API related endpoints are set to the authorisation level of `Anonymous`.
## Open API Metadata Configuration ##
To generate an Open API document, [OpenApiInfo object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#infoObject) needs to be defined. This information can be declared in **ONE OF THREE** places &ndash; `host.json`, `openapisettings.json` or `local.settings.json`.
This library looks for the information in the following order:
1. `host.json`
2. `openapisettings.json`
3. `local.settings.json` or App Settings blade on Azure
### `host.json` ###
Although it has not been officially accepted to be a part of `host.json`, the Open API metadata still can be stored in it like:
```json
{
...
"openApi": {
"info": {
"version": "1.0.0",
"title": "Open API Sample on Azure Functions",
"description": "A sample API that runs on Azure Functions 3.x using Open API specification - from **host. json**.",
"termsOfService": "https://github.com/Azure/azure-functions-openapi-extension",
"contact": {
"name": "Azure Functions Open API",
"email": "azfunc-openapi@microsoft.com",
"url": "https://github.com/Azure/azure-functions-openapi-extension/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}
...
}
```
### `openapisettings.json` ###
The Open API metadata can be defined in a separate file, `openapisettings.json` like:
```json
{
"info": {
"version": "1.0.0",
"title": "Open API Sample on Azure Functions",
"description": "A sample API that runs on Azure Functions 3.x using Open API specification - from **openapisettings.json**.",
"termsOfService": "https://github.com/Azure/azure-functions-openapi-extension",
"contact": {
"name": "Azure Functions Open API",
"email": "azfunc-openapi@microsoft.com",
"url": "https://github.com/Azure/azure-functions-openapi-extension/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}
```
### `local.settings.json` or App Settings Blade ###
On either your `local.settings.json` or App Settings on Azure Functions instance, those details can be set up like:
* `OpenApi__Info__Version`: **REQUIRED** Version of Open API document. This is not the version of Open API spec. eg. 1.0.0
* `OpenApi__Info__Title`: **REQUIRED** Title of Open API document. eg. Open API Sample on Azure Functions
* `OpenApi__Info__Description`: Description of Open API document. eg. A sample API that runs on Azure Functions either 1.x or 2.x using Open API specification.
* `OpenApi__Info__TermsOfService`: Terms of service URL. eg. https://github.com/aliencube/AzureFunctions.Extensions
* `OpenApi__Info__Contact__Name`: Name of contact. eg. Aliencube Community
* `OpenApi__Info__Contact__Email`: Email address for the contact. eg. no-reply@aliencube.org
* `OpenApi__Info__Contact__Url`: Contact URL. eg. https://github.com/aliencube/AzureFunctions.Extensions/issues
* `OpenApi__Info__License__Name`: **REQUIRED** License name. eg. MIT
* `OpenApi__Info__License__Url`: License URL. eg. http://opensource.org/licenses/MIT
> **NOTE**: In order to deploy Azure Functions v1 to Azure, the `AzureWebJobsScriptRoot` **MUST** be specified in the app settings section; otherwise it will throw an error that can't find `host.json`. Local debugging is fine, though. For more details, please visit [this page](https://docs.microsoft.com/azure/azure-functions/functions-app-settings#azurewebjobsscriptroot?WT.mc_id=azfuncextension-github-juyoo).

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

@ -0,0 +1,23 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This represents the model entity for API response of Swagger Pet Store.
/// </summary>
public class ApiResponse
{
/// <summary>
/// Gets or sets the code.
/// </summary>
public int? Code { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
public string Type { get; set; }
/// <summary>
/// Gets or sets the message.
/// </summary>
public string Message { get; set; }
}
}

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

@ -0,0 +1,18 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This represents the model entity for category of Swagger Pet Store.
/// </summary>
public class Category
{
/// <summary>
/// Gets or sets the category ID.
/// </summary>
public long? Id { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
public string Name { get; set; }
}
}

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

@ -0,0 +1,12 @@
using Newtonsoft.Json;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummyArrayResponseModel
{
public string Id { get; set; }
[JsonRequired]
public string JsonRequiredValue { get; set; }
}
}

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

@ -0,0 +1,14 @@
using System;
using Newtonsoft.Json;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummyDictionaryResponseModel
{
public Guid? Id { get; set; }
[JsonRequired]
public string JsonRequiredValue { get; set; }
}
}

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

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummyListModel
{
public List<DummyStringModel> ListValues { get; set; }
}
}

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

@ -0,0 +1,9 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummyRecursiveResponseModel
{
public string Id { get; set; }
public DummyRecursiveResponseModel RecursiveValue { get; set; }
}
}

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

@ -0,0 +1,37 @@
using System;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummyRequestModel
{
public Guid Id { get; set; }
public short ShortValue { get; set; }
public int IntValue { get; set; }
public long LongValue { get; set; }
public float SingleValue { get; set; }
public double DoubleValue { get; set; }
public decimal DecimalValue { get; set; }
public int? NullableIntValue { get; set; }
public bool BoolValue { get; set; }
public ShortEnum ShortEnumValue { get; set; }
public IntEnum IntEnumValue { get; set; }
public LongEnum LongEnumValue { get; set; }
public StringEnum StringEnumValue { get; set; }
public DateTime DateTimeValue { get; set; }
public DateTimeOffset DateTimeOffsetValue { get; set; }
}
}

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

@ -0,0 +1,50 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummyResponseModel
{
public DummySubResponseModel SubObjectValue { get; set; }
public DummyRecursiveResponseModel RecursiveObjectValue { get; set; }
public IDictionary<string, string> DictionaryStringValue { get; set; }
public Dictionary<string, int> DictionaryIntValue { get; set; }
public Dictionary<string, DummyDictionaryResponseModel> DictionaryObjectValue { get; set; }
public IList<string> ListStringValue { get; set; }
public List<int> ListIntValue { get; set; }
public List<DummyArrayResponseModel> ListObjectValue { get; set; }
public DummyArrayResponseModel[] ArrayObjectValue { get; set; }
public JObject JObjectValue { get; set; }
public JToken JTokenValue { get; set; }
[JsonProperty("CapitalisedJsonPropertyValue")]
public string JsonPropertyValue { get; set; }
[JsonIgnore]
public string JsonIgnoreValue { get; set; }
[JsonProperty("CapitalisedJsonPropertyRequiredValue", Required = Required.DisallowNull)]
public string JsonPropertyRequiredValue { get; set; } = "hello world";
[JsonRequired]
public string JsonRequiredValue { get; set; } = "lorem ipsum";
[OpenApiSchemaVisibility(OpenApiVisibilityType.Advanced)]
public string OpenApiSchemaVisibilityValue { get; set; }
}
}

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

@ -0,0 +1,11 @@
using System;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummyStringModel
{
public string StringValue { get; set; }
public Uri UriValue { get; set; }
}
}

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

@ -0,0 +1,12 @@
using Newtonsoft.Json;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public class DummySubResponseModel
{
public int Id { get; set; }
[JsonProperty("CapitalisedJsonRequiredValue", Required = Required.Always)]
public string JsonRequiredValue { get; set; }
}
}

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

@ -0,0 +1,8 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public enum IntEnum
{
Value1,
Value2
}
}

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

@ -0,0 +1,8 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public enum LongEnum : long
{
Value1,
Value2
}
}

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

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.csproj" />
</ItemGroup>
</Project>

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

@ -0,0 +1,23 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This specifies an enum that will be serialized as a number.
/// </summary>
public enum NumericEnum : short
{
/// <summary>
/// Identifies 1.
/// </summary>
FirstValue = 1,
/// <summary>
/// Identifies 2.
/// </summary>
SecondValue = 2,
/// <summary>
/// Identifies 3.
/// </summary>
ThirdValue = 3
}
}

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

@ -0,0 +1,40 @@
using System;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This represents the model entity for order of Swagger Pet Store.
/// </summary>
public class Order
{
/// <summary>
/// Gets or sets the order ID.
/// </summary>
public long? Id { get; set; }
/// <summary>
/// Gets or sets the pet ID.
/// </summary>
public long? PetId { get; set; }
/// <summary>
/// Gets or sets the quantity.
/// </summary>
public int? Quantity { get; set; }
/// <summary>
/// Gets or seets the date/time shipped.
/// </summary>
public DateTime? ShipDate { get; set; }
/// <summary>
/// Gets or sets the <see cref="OrderStatus"/> value.
/// </summary>
public OrderStatus? Status { get; set; }
/// <summary>
/// Gets or sets the value indicating whether the order is complete or not.
/// </summary>
public bool? Complete { get; set; }
}
}

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

@ -0,0 +1,32 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This specifies the order status.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum OrderStatus
{
/// <summary>
/// Identifies as "placed".
/// </summary>
[Display("placed")]
Placed = 1,
/// <summary>
/// Identifies as "approved".
/// </summary>
[Display("approved")]
Approved = 2,
/// <summary>
/// Identifies as "delivered".
/// </summary>
[Display("delivered")]
Delivered = 3
}
}

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

@ -0,0 +1,44 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This represents the model entity for pet of Swagger Pet Store.
/// </summary>
public class Pet
{
/// <summary>
/// Gets or sets the pet ID.
/// </summary>
public long? Id { get; set; }
/// <summary>
/// Gets or sets the category.
/// </summary>
public Category Category { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
[JsonRequired]
public string Name { get; set; }
/// <summary>
/// Gets or sets the list of photo URLs.
/// </summary>
[JsonRequired]
public List<string> PhotoUrls { get; set; } = new List<string>();
/// <summary>
/// Gets or sets the list of tags.
/// </summary>
public List<Tag> Tags { get; set; }
/// <summary>
/// Gets or sets the <see cref="PetStatus"/> value.
/// </summary>
public PetStatus? Status { get; set; }
}
}

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

@ -0,0 +1,32 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This specifices the pet status.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum PetStatus
{
/// <summary>
/// Identifies as "available".
/// </summary>
[Display("available")]
Available = 1,
/// <summary>
/// Identifies as "pending".
/// </summary>
[Display("pending")]
Pending = 2,
/// <summary>
/// Identifies as "sold".
/// </summary>
[Display("sold")]
Sold = 3
}
}

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

@ -0,0 +1,8 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
public enum ShortEnum : short
{
Value1,
Value2
}
}

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

@ -0,0 +1,22 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This specifies an enum that will be serialized as a string.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum StringEnum
{
/// <summary>
/// Identifies "off".
/// </summary>
Off = 0,
/// <summary>
/// Identifies "on".
/// </summary>
On = 1
}
}

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

@ -0,0 +1,18 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This represents the model entity for tag of Swagger Pet Store.
/// </summary>
public class Tag
{
/// <summary>
/// Gets or sets the tag ID.
/// </summary>
public long? Id { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
public string Name { get; set; }
}
}

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

@ -0,0 +1,48 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
/// <summary>
/// This represents the model entity for user of Swagger Pet Store.
/// </summary>
public class User
{
/// <summary>
/// Gets or sets the user ID.
/// </summary>
public long? Id { get; set; }
/// <summary>
/// Gets or sets the username.
/// </summary>
public string Username { get; set; }
/// <summary>
/// Gets or sets the first name.
/// </summary>
public string FirstName { get; set; }
/// <summary>
/// Gets or sets the last name.
/// </summary>
public string LastName { get; set; }
/// <summary>
/// Gets or sets the email.
/// </summary>
public string Email { get; set; }
/// <summary>
/// Gets or sets the password.
/// </summary>
public string Password { get; set; }
/// <summary>
/// Gets or sets the phone number.
/// </summary>
public string Phone { get; set; }
/// <summary>
/// Gets or sets the user status value.
/// </summary>
public int? UserStatus { get; set; }
}
}

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

@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services
{
/// <summary>
/// This represents the service entity for the sample HTTP trigger.
/// </summary>
public class DummyHttpService : IDummyHttpService
{
/// <inheritdoc />
public async Task<List<DummyResponseModel>> GetDummies()
{
var result = new List<DummyResponseModel>()
{
new DummyResponseModel(),
};
return await Task.FromResult(result).ConfigureAwait(false);
}
public async Task<DummyResponseModel> AddDummy()
{
var result = new DummyResponseModel();
return await Task.FromResult(result).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services
{
/// <summary>
/// This provides interfaces to <see cref="DummyHttpService"/>.
/// </summary>
public interface IDummyHttpService
{
/// <summary>
/// Gets the list of <see cref="DummyResponseModel"/> objects.
/// </summary>
/// <returns>Returns the list of <see cref="DummyResponseModel"/> objects.</returns>
Task<List<DummyResponseModel>> GetDummies();
/// <summary>
/// Adds dummy data.
/// </summary>
/// <returns>Returns the <see cref="DummyResponseModel"/> instance.</returns>
Task<DummyResponseModel> AddDummy();
}
}

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

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.csproj" />
</ItemGroup>
</Project>

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

@ -0,0 +1,264 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# Azure Functions localsettings file
#local.settings.json
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

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

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2IoC
{
public class DummyHttpTrigger
{
private readonly IDummyHttpService _service;
public DummyHttpTrigger(IDummyHttpService service)
{
this._service = service ?? throw new ArgumentNullException(nameof(service));
}
[FunctionName(nameof(DummyHttpTrigger.GetDummies))]
[OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyResponseModel>), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")]
public async Task<IActionResult> GetDummies(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyResponseModel>()
{
new DummyResponseModel(),
};
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.AddDummy))]
[OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")]
public async Task<IActionResult> AddDummy(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new DummyResponseModel();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.UpdateDummies))]
[OpenApiOperation(operationId: "updateDummies", tags: new[] { "dummy" }, Summary = "Updates a list of dummies", Description = "This updates a list of dummies.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyListModel), Required = true, Description = "Dummy list model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyStringModel>), Summary = "Dummy response", Description = "This returns the dummy response")]
public async Task<IActionResult> UpdateDummies(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyStringModel>();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<!--<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="3.0.0" />-->
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.28" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Azure.WebJobs.Extensions.OpenApi\Microsoft.Azure.WebJobs.Extensions.OpenApi.csproj" />
<ProjectReference Include="..\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="openapisettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<Compile Include="..\..\templates\OpenApiEndpints\IOpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTrigger.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2IoC
{
public class PetStoreHttpTrigger
{
private readonly IDummyHttpService _service;
public PetStoreHttpTrigger(IDummyHttpService service)
{
this._service = service ?? throw new ArgumentNullException(nameof(service));
}
[FunctionName(nameof(PetStoreHttpTrigger.AddPet))]
[OpenApiOperation(operationId: "addPet", tags: new[] { "pet" }, Summary = "Add a new pet to the store", Description = "This add a new pet to the store.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be added to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "New pet details added", Description = "New pet details added")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Invalid input", Description = "Invalid input")]
public async Task<IActionResult> AddPet(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.UpdatePet))]
[OpenApiOperation(operationId: "updatePet", tags: new[] { "pet" }, Summary = "Update an existing pet", Description = "This updates an existing pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be updated to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "Pet details updated", Description = "Pet details updated")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Validation exception", Description = "Validation exception")]
public async Task<IActionResult> UpdatePet(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByStatus))]
[OpenApiOperation(operationId: "findPetsByStatus", tags: new[] { "pet" }, Summary = "Finds Pets by status", Description = "Multiple status values can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "status", In = ParameterLocation.Query, Required = true, Type = typeof(List<PetStatus>), Summary = "Pet status value", Description = "Status values that need to be considered for filter", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid status value", Description = "Invalid status value")]
public async Task<IActionResult> FindByStatus(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "pet/findByStatus")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByTags))]
[OpenApiOperation(operationId: "findPetsByTags", tags: new[] { "pet" }, Summary = "Finds Pets by tags", Description = "Muliple tags can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "tags", In = ParameterLocation.Query, Required = true, Type = typeof(List<string>), Summary = "Tags to filter by", Description = "Tags to filter by", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid tag value", Description = "Invalid tag value")]
public async Task<IActionResult> FindByTags(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/findByTags")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.GetPetById))]
[OpenApiOperation(operationId: "getPetById", tags: new[] { "pet" }, Summary = "Find pet by ID", Description = "Returns a single pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "petId", In = ParameterLocation.Path, Required = true, Type = typeof(long), Summary = "ID of pet to return", Description = "ID of pet to return", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
public async Task<IActionResult> GetPetById(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/{petId}")] HttpRequest req,
long petId,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage.emulator",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,26 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2IoC #
## Getting Started ##
### Restore NuGet Packages ###
Run the following command to restore all necessary NuGet packages into the project.
```bash
dotnet restore .
```
### Run Function App ###
Run the Function app locally.
```bash
func start
```
Open a web browser and visit the page.
```txt
http://localhost:7071/api/swagger/ui
```

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

@ -0,0 +1,20 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2IoC.StartUp))]
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2IoC
{
/// <summary>
/// This represents the entity to be invoked during the runtime startup.
/// </summary>
public class StartUp : FunctionsStartup
{
/// <inheritdoc />
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<IDummyHttpService, DummyHttpService>();
}
}
}

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

@ -0,0 +1,11 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingExcludedTypes": "Request",
"samplingSettings": {
"isEnabled": true
}
}
}
}

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

@ -0,0 +1,9 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"OpenApi__ApiKey": ""
}
}

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

@ -0,0 +1,17 @@
{
"info": {
"version": "3.0.0",
"title": "Open API Sample on Azure Functions (IoC)",
"description": "A sample API that runs on Azure Functions (IoC) 2.x using Open API specification - from **openapisettings.json**.",
"termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions",
"contact": {
"name": "Aliencube Community",
"email": "no-reply@aliencube.org",
"url": "https://github.com/aliencube/AzureFunctions.Extensions/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}

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

@ -0,0 +1,264 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# Azure Functions localsettings file
#local.settings.json
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

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

@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2Static
{
public static class DummyHttpTrigger
{
[FunctionName(nameof(DummyHttpTrigger.GetDummies))]
[OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyResponseModel>), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")]
public static async Task<IActionResult> GetDummies(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyResponseModel>()
{
new DummyResponseModel(),
};
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.AddDummy))]
[OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")]
public static async Task<IActionResult> AddDummy(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new DummyResponseModel();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.UpdateDummies))]
[OpenApiOperation(operationId: "updateDummies", tags: new[] { "dummy" }, Summary = "Updates a list of dummies", Description = "This updates a list of dummies.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyListModel), Required = true, Description = "Dummy list model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyStringModel>), Summary = "Dummy response", Description = "This returns the dummy response")]
public static async Task<IActionResult> UpdateDummies(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyStringModel>();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<!--<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="3.0.0" />-->
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.28" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Azure.WebJobs.Extensions.OpenApi\Microsoft.Azure.WebJobs.Extensions.OpenApi.csproj" />
<ProjectReference Include="..\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<Compile Include="..\..\templates\OpenApiEndpints\IOpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTrigger.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,84 @@
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2Static
{
public static class PetStoreHttpTrigger
{
[FunctionName(nameof(PetStoreHttpTrigger.AddPet))]
[OpenApiOperation(operationId: "addPet", tags: new[] { "pet" }, Summary = "Add a new pet to the store", Description = "This add a new pet to the store.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be added to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "New pet details added", Description = "New pet details added")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Invalid input", Description = "Invalid input")]
public static async Task<IActionResult> AddPet(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.UpdatePet))]
[OpenApiOperation(operationId: "updatePet", tags: new[] { "pet" }, Summary = "Update an existing pet", Description = "This updates an existing pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be updated to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "Pet details updated", Description = "Pet details updated")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Validation exception", Description = "Validation exception")]
public static async Task<IActionResult> UpdatePet(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByStatus))]
[OpenApiOperation(operationId: "findPetsByStatus", tags: new[] { "pet" }, Summary = "Finds Pets by status", Description = "Multiple status values can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "status", In = ParameterLocation.Query, Required = true, Type = typeof(List<PetStatus>), Summary = "Pet status value", Description = "Status values that need to be considered for filter", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid status value", Description = "Invalid status value")]
public static async Task<IActionResult> FindByStatus(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "pet/findByStatus")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByTags))]
[OpenApiOperation(operationId: "findPetsByTags", tags: new[] { "pet" }, Summary = "Finds Pets by tags", Description = "Muliple tags can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "tags", In = ParameterLocation.Query, Required = true, Type = typeof(List<string>), Summary = "Tags to filter by", Description = "Tags to filter by", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid tag value", Description = "Invalid tag value")]
public static async Task<IActionResult> FindByTags(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/findByTags")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.GetPetById))]
[OpenApiOperation(operationId: "getPetById", tags: new[] { "pet" }, Summary = "Find pet by ID", Description = "Returns a single pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "petId", In = ParameterLocation.Path, Required = true, Type = typeof(long), Summary = "ID of pet to return", Description = "ID of pet to return", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
public static async Task<IActionResult> GetPetById(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/{petId}")] HttpRequest req,
long petId,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage.emulator",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,26 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV2Static #
## Getting Started ##
### Restore NuGet Packages ###
Run the following command to restore all necessary NuGet packages into the project.
```bash
dotnet restore .
```
### Run Function App ###
Run the Function app locally.
```bash
func start
```
Open a web browser and visit the page.
```txt
http://localhost:7071/api/swagger/ui
```

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

@ -0,0 +1,28 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"openApi": {
"info": {
"version": "3.0.0",
"title": "Open API Sample on Azure Functions (STATIC)",
"description": "A sample API that runs on Azure Functions (STATIC) 2.x using Open API specification - from **host.json**.",
"termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions",
"contact": {
"name": "Aliencube Community",
"email": "no-reply@aliencube.org",
"url": "https://github.com/aliencube/AzureFunctions.Extensions/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}
}

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

@ -0,0 +1,9 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"OpenApi__ApiKey": ""
}
}

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

@ -0,0 +1,266 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# Azure Functions localsettings file
#local.settings.json
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
OpenApi/

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

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

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

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to .NET Functions",
"type": "coreclr",
"request": "attach",
"processId": "${command:azureFunctions.pickProcess}"
}
]
}

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

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

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

@ -0,0 +1,69 @@
{
"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",
"--configuration",
"Release",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"type": "process",
"dependsOn": "clean release",
"problemMatcher": "$msCompile"
},
{
"type": "func",
"dependsOn": "build",
"options": {
"cwd": "${workspaceFolder}/bin/Debug/netcoreapp3.1"
},
"command": "host start",
"isBackground": true,
"problemMatcher": "$func-watch"
}
]
}

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

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3IoC
{
public class DummyHttpTrigger
{
private readonly IDummyHttpService _service;
public DummyHttpTrigger(IDummyHttpService service)
{
this._service = service ?? throw new ArgumentNullException(nameof(service));
}
[FunctionName(nameof(DummyHttpTrigger.GetDummies))]
[OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyResponseModel>), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")]
public async Task<IActionResult> GetDummies(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyResponseModel>()
{
new DummyResponseModel(),
};
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.AddDummy))]
[OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")]
public async Task<IActionResult> AddDummy(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new DummyResponseModel();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.UpdateDummies))]
[OpenApiOperation(operationId: "updateDummies", tags: new[] { "dummy" }, Summary = "Updates a list of dummies", Description = "This updates a list of dummies.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyListModel), Required = true, Description = "Dummy list model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyStringModel>), Summary = "Dummy response", Description = "This returns the dummy response")]
public async Task<IActionResult> UpdateDummies(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyStringModel>();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<!--<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="3.0.0" />-->
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Azure.WebJobs.Extensions.OpenApi\Microsoft.Azure.WebJobs.Extensions.OpenApi.csproj" />
<ProjectReference Include="..\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="openapisettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<Compile Include="..\..\templates\OpenApiEndpints\IOpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTrigger.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3IoC
{
public class PetStoreHttpTrigger
{
private readonly IDummyHttpService _service;
public PetStoreHttpTrigger(IDummyHttpService service)
{
this._service = service ?? throw new ArgumentNullException(nameof(service));
}
[FunctionName(nameof(PetStoreHttpTrigger.AddPet))]
[OpenApiOperation(operationId: "addPet", tags: new[] { "pet" }, Summary = "Add a new pet to the store", Description = "This add a new pet to the store.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be added to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "New pet details added", Description = "New pet details added")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Invalid input", Description = "Invalid input")]
public async Task<IActionResult> AddPet(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.UpdatePet))]
[OpenApiOperation(operationId: "updatePet", tags: new[] { "pet" }, Summary = "Update an existing pet", Description = "This updates an existing pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be updated to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "Pet details updated", Description = "Pet details updated")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Validation exception", Description = "Validation exception")]
public async Task<IActionResult> UpdatePet(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByStatus))]
[OpenApiOperation(operationId: "findPetsByStatus", tags: new[] { "pet" }, Summary = "Finds Pets by status", Description = "Multiple status values can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "status", In = ParameterLocation.Query, Required = true, Type = typeof(List<PetStatus>), Summary = "Pet status value", Description = "Status values that need to be considered for filter", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid status value", Description = "Invalid status value")]
public async Task<IActionResult> FindByStatus(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "pet/findByStatus")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByTags))]
[OpenApiOperation(operationId: "findPetsByTags", tags: new[] { "pet" }, Summary = "Finds Pets by tags", Description = "Muliple tags can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "tags", In = ParameterLocation.Query, Required = true, Type = typeof(List<string>), Summary = "Tags to filter by", Description = "Tags to filter by", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid tag value", Description = "Invalid tag value")]
public async Task<IActionResult> FindByTags(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/findByTags")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.GetPetById))]
[OpenApiOperation(operationId: "getPetById", tags: new[] { "pet" }, Summary = "Find pet by ID", Description = "Returns a single pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "petId", In = ParameterLocation.Path, Required = true, Type = typeof(long), Summary = "ID of pet to return", Description = "ID of pet to return", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
public async Task<IActionResult> GetPetById(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/{petId}")] HttpRequest req,
long petId,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage.emulator",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,26 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3IoC #
## Getting Started ##
### Restore NuGet Packages ###
Run the following command to restore all necessary NuGet packages into the project.
```bash
dotnet restore .
```
### Run Function App ###
Run the Function app locally.
```bash
func start
```
Open a web browser and visit the page.
```txt
http://localhost:7071/api/swagger/ui
```

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

@ -0,0 +1,20 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Services;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3IoC.StartUp))]
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3IoC
{
/// <summary>
/// This represents the entity to be invoked during the runtime startup.
/// </summary>
public class StartUp : FunctionsStartup
{
/// <inheritdoc />
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<IDummyHttpService, DummyHttpService>();
}
}
}

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

@ -0,0 +1,11 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
}
}

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

@ -0,0 +1,9 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"OpenApi__ApiKey": ""
},
}

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

@ -0,0 +1,17 @@
{
"info": {
"version": "3.0.0",
"title": "Open API Sample on Azure Functions (IoC)",
"description": "A sample API that runs on Azure Functions (IoC) 3.x using Open API specification - from **openapisettings.json**.",
"termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions",
"contact": {
"name": "Aliencube Community",
"email": "no-reply@aliencube.org",
"url": "https://github.com/aliencube/AzureFunctions.Extensions/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}

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

@ -0,0 +1,266 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# Azure Functions localsettings file
#local.settings.json
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
OpenApi/

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

@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3Static
{
public static class DummyHttpTrigger
{
[FunctionName(nameof(DummyHttpTrigger.GetDummies))]
[OpenApiOperation(operationId: "getDummies", tags: new[] { "dummy" }, Summary = "Gets the list of dummies", Description = "This gets the list of dummies.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "Dummy name", Description = "Dummy name", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "switch", In = ParameterLocation.Path, Required = true, Type = typeof(StringEnum), Summary = "Dummy switch", Description = "Dummy switch", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyResponseModel>), Summary = "List of the dummy responses", Description = "This returns the list of dummy responses")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Name not found", Description = "Name parameter is not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid switch", Description = "Switch parameter is not valid")]
public static async Task<IActionResult> GetDummies(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyResponseModel>()
{
new DummyResponseModel(),
};
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.AddDummy))]
[OpenApiOperation(operationId: "addDummy", tags: new[] { "dummy" }, Summary = "Adds a dummy", Description = "This adds a dummy.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyRequestModel), Required = true, Description = "Dummy request model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyResponseModel), Summary = "Dummy response", Description = "This returns the dummy response")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid request payload", Description = "Request payload is not valid")]
public static async Task<IActionResult> AddDummy(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new DummyResponseModel();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
[FunctionName(nameof(DummyHttpTrigger.UpdateDummies))]
[OpenApiOperation(operationId: "updateDummies", tags: new[] { "dummy" }, Summary = "Updates a list of dummies", Description = "This updates a list of dummies.", Visibility = OpenApiVisibilityType.Advanced)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyListModel), Required = true, Description = "Dummy list model")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyStringModel>), Summary = "Dummy response", Description = "This returns the dummy response")]
public static async Task<IActionResult> UpdateDummies(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "dummies")] HttpRequest req,
ILogger log)
{
var content = new List<DummyStringModel>();
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<!--<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="3.0.0" />-->
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Azure.WebJobs.Extensions.OpenApi\Microsoft.Azure.WebJobs.Extensions.OpenApi.csproj" />
<ProjectReference Include="..\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models\Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<Compile Include="..\..\templates\OpenApiEndpints\IOpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTriggerContext.cs" />
<Compile Include="..\..\templates\OpenApiEndpints\OpenApiHttpTrigger.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,85 @@
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3Static
{
public static class PetStoreHttpTrigger
{
[FunctionName(nameof(PetStoreHttpTrigger.AddPet))]
[OpenApiOperation(operationId: "addPet", tags: new[] { "pet" }, Summary = "Add a new pet to the store", Description = "This add a new pet to the store.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be added to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "New pet details added", Description = "New pet details added")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Invalid input", Description = "Invalid input")]
public static async Task<IActionResult> AddPet(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.UpdatePet))]
[OpenApiOperation(operationId: "updatePet", tags: new[] { "pet" }, Summary = "Update an existing pet", Description = "This updates an existing pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(Pet), Required = true, Description = "Pet object that needs to be updated to the store")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "Pet details updated", Description = "Pet details updated")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.MethodNotAllowed, Summary = "Validation exception", Description = "Validation exception")]
public static async Task<IActionResult> UpdatePet(
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "pet")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByStatus))]
[OpenApiOperation(operationId: "findPetsByStatus", tags: new[] { "pet" }, Summary = "Finds Pets by status", Description = "Multiple status values can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
//[OpenApiParameter(name: "status", In = ParameterLocation.Query, Required = true, Type = typeof(PetStatus), Summary = "Pet status value", Description = "Status values that need to be considered for filter", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "status", In = ParameterLocation.Query, Required = true, Type = typeof(List<PetStatus>), Summary = "Pet status value", Description = "Status values that need to be considered for filter", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid status value", Description = "Invalid status value")]
public static async Task<IActionResult> FindByStatus(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "pet/findByStatus")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.FindByTags))]
[OpenApiOperation(operationId: "findPetsByTags", tags: new[] { "pet" }, Summary = "Finds Pets by tags", Description = "Muliple tags can be provided with comma separated strings.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "tags", In = ParameterLocation.Query, Required = true, Type = typeof(List<string>), Summary = "Tags to filter by", Description = "Tags to filter by", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<Pet>), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid tag value", Description = "Invalid tag value")]
public static async Task<IActionResult> FindByTags(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/findByTags")] HttpRequest req,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
[FunctionName(nameof(PetStoreHttpTrigger.GetPetById))]
[OpenApiOperation(operationId: "getPetById", tags: new[] { "pet" }, Summary = "Find pet by ID", Description = "Returns a single pet.", Visibility = OpenApiVisibilityType.Important)]
[OpenApiParameter(name: "petId", In = ParameterLocation.Path, Required = true, Type = typeof(long), Summary = "ID of pet to return", Description = "ID of pet to return", Visibility = OpenApiVisibilityType.Important)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Pet), Summary = "successful operation", Description = "successful operation")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.BadRequest, Summary = "Invalid ID supplied", Description = "Invalid ID supplied")]
[OpenApiResponseWithoutBody(statusCode: HttpStatusCode.NotFound, Summary = "Pet not found", Description = "Pet not found")]
public static async Task<IActionResult> GetPetById(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "pet/{petId}")] HttpRequest req,
long petId,
ILogger log)
{
return await Task.FromResult(new OkResult()).ConfigureAwait(false);
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,8 @@
{
"dependencies": {
"storage1": {
"type": "storage.emulator",
"connectionId": "AzureWebJobsStorage"
}
}
}

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

@ -0,0 +1,26 @@
# Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionAppV3Static #
## Getting Started ##
### Restore NuGet Packages ###
Run the following command to restore all necessary NuGet packages into the project.
```bash
dotnet restore .
```
### Run Function App ###
Run the Function app locally.
```bash
func start
```
Open a web browser and visit the page.
```txt
http://localhost:7071/api/swagger/ui
```

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

@ -0,0 +1,28 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"openApi": {
"info": {
"version": "3.0.0",
"title": "Open API Sample on Azure Functions (STATIC)",
"description": "A sample API that runs on Azure Functions (STATIC) 3.x using Open API specification - from **host.json**.",
"termsOfService": "https://github.com/aliencube/AzureFunctions.Extensions",
"contact": {
"name": "Aliencube Community",
"email": "no-reply@aliencube.org",
"url": "https://github.com/aliencube/AzureFunctions.Extensions/issues"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
}
}
}

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

@ -0,0 +1,9 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"OpenApi__ApiKey": ""
}
}

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

@ -0,0 +1,34 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.Resolvers;
using Microsoft.Extensions.Configuration;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings
{
/// <summary>
/// This represents the base app settings entity.
/// </summary>
public abstract class AppSettingsBase
{
/// <summary>
/// Initializes a new instance of the <see cref="AppSettingsBase"/> class.
/// </summary>
protected AppSettingsBase()
{
this.Config = ConfigurationResolver.Resolve();
}
/// <summary>
/// Gets the <see cref="IConfiguration"/> instance.
/// </summary>
protected virtual IConfiguration Config { get; }
/// <summary>
/// Gets the base path
/// </summary>
/// <returns></returns>
protected string GetBasePath()
{
return ConfigurationResolver.GetBasePath(this.Config);
}
}
}

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

@ -0,0 +1,28 @@
using System.Runtime.InteropServices;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.Extensions
{
/// <summary>
/// This represents the entity to determine operating system.
/// </summary>
public static class OperationSystem
{
/// <summary>
/// Gets the value indicating whether the OS is Windows or not.
/// </summary>
/// <returns><c>True</c>, if the OS is Windows; otherwise returns <c>False</c>.</returns>
public static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
/// <summary>
/// Gets the value indicating whether the OS is Mac or not.
/// </summary>
/// <returns><c>True</c>, if the OS is Mac; otherwise returns <c>False</c>.</returns>
public static bool IsMacOs() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
/// <summary>
/// Gets the value indicating whether the OS is Linux or not.
/// </summary>
/// <returns><c>True</c>, if the OS is Linux; otherwise returns <c>False</c>.</returns>
public static bool IsLinux() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
}
}

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

@ -0,0 +1,35 @@
using System;
using Microsoft.Extensions.Configuration;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.Extensions
{
/// <summary>
/// This represents the extension entity for <see cref="ConfigurationBinder"/> class.
/// </summary>
public static class ConfigurationBinderExtensions
{
/// <summary>
/// Gets the instance from the configuration.
/// </summary>
/// <typeparam name="T">Type of instance.</typeparam>
/// <param name="configuration"><see cref="IConfiguration"/> instance.</param>
/// <param name="key">Configuration key.</param>
/// <returns>Returns the instance from the configuration.</returns>
public static T Get<T>(this IConfiguration configuration, string key = null)
{
var instance = Activator.CreateInstance<T>();
if (string.IsNullOrWhiteSpace(key))
{
configuration.Bind(instance);
return instance;
}
configuration.Bind(key, instance);
return instance;
}
}
}

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

@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>true</IsPackable>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageId>Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings</PackageId>
<Owners>Microsoft</Owners>
<Authors>Microsoft</Authors>
<Company>Microsoft</Company>
<Version>1.0.0</Version>
<Title>Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings</Title>
<Product>Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings</Product>
<Summary>This package provides a base app settings capability deserialising environment variables into IConfiguration object.</Summary>
<Description>This package provides a base app settings capability deserialising environment variables into IConfiguration object.</Description>
<PackageTags>Azure-Functions, Configuration, AppSettings</PackageTags>
<Copyright>Microsoft</Copyright>
<PackageLicenseUrl>https://github.com/Azure/azure-functions-openapi-extension/blob/main/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/Azure/azure-functions-openapi-extension</PackageProjectUrl>
<RepositoryUrl>https://github.com/Azure/azure-functions-openapi-extension</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<AssemblyName>Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings</AssemblyName>
<RootNamespace>Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<DocumentationFile>bin\Debug\netstandard2.0\Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<DocumentationFile>bin\Release\netstandard2.0\Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.1" />
</ItemGroup>
</Project>

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

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Configuration;
using OperatingSystem = Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.Extensions.OperationSystem;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings.Resolvers
{
/// <summary>
/// This represents the resolver entity for configuration.
/// </summary>
public static class ConfigurationResolver
{
/// <summary>
/// Gets the <see cref="IConfiguration"/> instance from the environment variables - either local.settings.json or App Settings blade.
/// </summary>
public static IConfiguration Resolve()
{
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
return config;
}
/// <summary>
/// Gets the configuration value.
/// </summary>
/// <typeparam name="T">Type of return value.</typeparam>
/// <param name="key">Key for lookup.</param>
/// <param name="config"><see cref="IConfiguration"/> instance from the environment variables - either local.settings.json or App Settings blade.</param>
/// <returns>Returns the value.</returns>
public static T GetValue<T>(string key, IConfiguration config = null)
{
if (config == null)
{
config = Resolve();
}
var value = config.GetValue<T>(key);
return value;
}
/// <summary>
/// Gets the base path of the executing Azure Functions assembly.
/// </summary>
/// <param name="environmentVariables"><see cref="IConfiguration"/> instance representing environment variables from either local.settings.json or App Settings blade.</param>
/// <returns>Returns the base path of the executing Azure Functions assembly.</returns>
public static string GetBasePath(IConfiguration environmentVariables)
{
var location = Assembly.GetExecutingAssembly().Location;
var segments = location.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries).ToList();
var basePath = string.Join(Path.DirectorySeparatorChar.ToString(), segments.Take(CountDirectories(segments)));
if (!OperatingSystem.IsWindows())
{
basePath = $"/{basePath}";
}
return basePath;
}
private static int CountDirectories(List<string> segments)
{
var bin = segments[segments.Count - 2];
if (bin == "bin")
{
return segments.Count - 2;
}
return segments.Count - 1;
}
}
}

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

@ -0,0 +1,6 @@
bin/
obj/
Properties/
*.csproj
*.csproj.user
*.cs

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

@ -0,0 +1,27 @@
{
// 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": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/netcoreapp2.1/azfuncopenapi.dll",
"args": [],
"cwd": "${workspaceFolder}",
// 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}"
}
]
}

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

@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/Aliencube.AzureFunctions.Extensions.OpenApi.CLI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

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

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<AssemblyName>azfuncopenapi</AssemblyName>
</PropertyGroup>
<ItemGroup Condition="'$(Configuration)'=='Release'">
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi.Core" Version="3.1.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Cocona.Lite" Version="1.4.0" />
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.5" />
<PackageReference Include="Moq" Version="4.14.5" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<ProjectReference Include="..\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core\Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.csproj" />
</ItemGroup>
</Project>

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

@ -0,0 +1,110 @@
using System;
using System.IO;
using System.Text;
using Cocona;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors;
using Moq;
using Newtonsoft.Json.Serialization;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI
{
/// <summary>
/// This represents the console app entity.
/// </summary>
public class Program
{
private static readonly char directorySeparator = Path.DirectorySeparatorChar;
/// <summary>
/// Invokes the console app.
/// </summary>
/// <param name="args">List of arguments.</param>
public static void Main(string[] args)
{
CoconaLiteApp.Run<Program>(args);
}
/// <summary>
/// Generates the Open API document.
/// </summary>
/// <param name="project">Project path.</param>
/// <param name="configuration">Copile configuration.</param>
/// <param name="version">Open API version.</param>
/// <param name="format">Open API output format.</param>
/// <param name="output">Output path.</param>
/// <param name="console">Value indicating whether to render the document on console or not.</param>
public void Generate(
[Option('p', Description = "Project path. Default is current directory")] string project = ".",
[Option('c', Description = "Configuration. Default is 'Debug'")] string configuration = "Debug",
[Option('t', Description = "Target framework. Default is 'netcoreapp2.1'")] string target = "netcoreapp2.1",
[Option('v', Description = "Open API spec version. Value can be either 'v2' or 'v3'. Default is 'v2'")] OpenApiVersionType version = OpenApiVersionType.V2,
[Option('f', Description = "Open API output format. Value can be either 'json' or 'yaml'. Default is 'yaml'")] OpenApiFormatType format = OpenApiFormatType.Json,
[Option('o', Description = "Generated Open API output location. Default is 'output'")] string output = "output",
bool console = false)
{
var pi = default(ProjectInfo);
try
{
pi = new ProjectInfo(project, configuration, target);
}
catch
{
return;
}
var req = new Mock<HttpRequest>();
req.SetupGet(p => p.Scheme).Returns("http");
req.SetupGet(p => p.Host).Returns(new HostString("localhost", 7071));
var filter = new RouteConstraintFilter();
var acceptor = new OpenApiSchemaAcceptor();
var namingStrategy = new CamelCaseNamingStrategy();
var collection = VisitorCollection.CreateInstance();
var helper = new DocumentHelper(filter, acceptor);
var document = new Document(helper);
var swagger = default(string);
try
{
swagger = document.InitialiseDocument()
.AddMetadata(pi.OpenApiInfo)
.AddServer(req.Object, pi.HostJsonHttpSettings.RoutePrefix)
.AddNamingStrategy(namingStrategy)
.AddVisitors(collection)
.Build(pi.CompiledDllPath)
.RenderAsync(version.ToOpenApiSpecVersion(), format.ToOpenApiFormat())
.Result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
if (console)
{
Console.WriteLine(swagger);
}
var outputpath = Path.IsPathFullyQualified(output)
? output
: $"{pi.CompiledPath}{directorySeparator}{output}";
if (!Directory.Exists(outputpath))
{
Directory.CreateDirectory(outputpath);
}
File.WriteAllText($"{outputpath}{directorySeparator}swagger.{format.ToDisplayName()}", swagger, Encoding.UTF8);
}
}
}

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

@ -0,0 +1,310 @@
using System;
using System.IO;
using System.Linq;
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;
using Newtonsoft.Json;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI
{
/// <summary>
/// This represents the project info entity.
/// </summary>
public class ProjectInfo
{
private static readonly char directorySeparator = System.IO.Path.DirectorySeparatorChar;
private string _projectPath;
private string _filename;
private string _configuration;
private string _targetFramework;
/// <summary>
/// Initializes a new instance of the <see cref="ProjectInfo"/> class.
/// </summary>
public ProjectInfo()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ProjectInfo"/> class.
/// </summary>
/// <param name="projectPath">Project path.</param>
/// <param name="configuration">Configuration value.</param>
/// <param name="targetFramework">Target framework.</param>
public ProjectInfo(string projectPath, string configuration, string targetFramework)
{
this.SetProjectPath(projectPath.ThrowIfNullOrWhiteSpace());
this._configuration = configuration.ThrowIfNullOrWhiteSpace();
this._targetFramework = targetFramework.ThrowIfNullOrWhiteSpace();
this.SetHostSettings();
this.SetOpenApiInfo();
}
/// <summary>
/// Gets or sets the fully qualified project path.
/// </summary>
public virtual string Path
{
get
{
return this._projectPath;
}
set
{
this.SetProjectPath(value);
}
}
/// <summary>
/// Gets or sets the compile configuration value.
/// </summary>
public virtual string Configuration
{
get
{
return this._configuration;
}
set
{
this._configuration = value;
}
}
/// <summary>
/// Gets or sets the compile target framework value.
/// </summary>
public virtual string TargetFramework
{
get
{
return this._targetFramework;
}
set
{
this._targetFramework = value;
}
}
/// <summary>
/// Gets the project filename, ie) *.csproj
/// </summary>
public virtual string Filename
{
get
{
return this._filename;
}
}
/// <summary>
/// Gets the fully qualified compiled directory path.
/// </summary>
public virtual string CompiledPath
{
get
{
this.Path.ThrowIfNullOrWhiteSpace();
this.Configuration.ThrowIfNullOrWhiteSpace();
this.TargetFramework.ThrowIfNullOrWhiteSpace();
return $"{this.Path.TrimEnd(directorySeparator)}{directorySeparator}bin{directorySeparator}{this.Configuration}{directorySeparator}{this.TargetFramework}";
}
}
/// <summary>
/// Gets the fully qualified compiled .dll file path.
/// </summary>
public virtual string CompiledDllPath
{
get
{
this.CompiledPath.ThrowIfNullOrWhiteSpace();
this.Filename.ThrowIfNullOrWhiteSpace();
return $"{this.CompiledPath}{directorySeparator}bin{directorySeparator}{this.Filename}".Replace(".csproj", ".dll");
}
}
/// <summary>
/// Gets the fully qualified file path of host.json.
/// </summary>
public virtual string HostJsonPath
{
get
{
this.CompiledPath.ThrowIfNullOrWhiteSpace();
return $"{this.CompiledPath}{directorySeparator}host.json";
}
}
/// <summary>
/// Gets the host.json settings.
/// </summary>
public virtual IConfiguration HostSettings { get; private set; }
/// <summary>
/// Gets the HTTP settings in host.json.
/// </summary>
public virtual HttpSettings HostJsonHttpSettings { get; private set; }
/// <summary>
/// Gets the fully qualified file path of local.settings.json
/// </summary>
public virtual string LocalSettingsJsonPath
{
get
{
this.CompiledPath.ThrowIfNullOrWhiteSpace();
return $"{this.CompiledPath}{directorySeparator}local.settings.json";
}
}
/// <summary>
/// Gets the fully qualified file path of openapisettings.json
/// </summary>
public virtual string OpenApiSettingsJsonPath
{
get
{
this.CompiledPath.ThrowIfNullOrWhiteSpace();
return $"{this.CompiledPath}{directorySeparator}openapisettings.json";
}
}
/// <summary>
/// Gets the <see cref="OpenApiInfo"/> instance.
/// </summary>
public virtual OpenApiInfo OpenApiInfo { get; private set; }
private void SetProjectPath(string path)
{
if (path.IsNullOrWhiteSpace() || path == ".")
{
this._projectPath = Environment.CurrentDirectory.TrimEnd(directorySeparator);
var filepath = Directory.GetFiles(this._projectPath, "*.csproj").SingleOrDefault();
if (filepath.IsNullOrWhiteSpace())
{
throw new FileNotFoundException();
}
var csproj = new FileInfo(filepath);
this._filename = csproj.Name;
}
var fqpath =
#if NET461
System.IO.Path.IsPathRooted(path)
#else
System.IO.Path.IsPathFullyQualified(path)
#endif
? path
: $"{Environment.CurrentDirectory.TrimEnd(directorySeparator)}{directorySeparator}{path}";
if (fqpath.EndsWith(".csproj"))
{
var csproj = new FileInfo(fqpath);
this._projectPath = csproj.DirectoryName.TrimEnd(directorySeparator);
this._filename = csproj.Name;
}
var di = new DirectoryInfo(fqpath);
this._projectPath = di.FullName.TrimEnd(directorySeparator);
var segments = di.FullName.Split(new[] { directorySeparator }, StringSplitOptions.RemoveEmptyEntries);
this._filename = $"{segments.Last()}.csproj";
}
private void SetHostSettings()
{
this.HostJsonPath.ThrowIfNullOrWhiteSpace();
var host = new ConfigurationBuilder()
.SetBasePath(this.HostJsonPath.Replace("host.json", ""))
.AddJsonFile("host.json")
.Build();
this.HostSettings = host;
var version = this.HostSettings.GetSection("version").Value;
this.HostJsonHttpSettings = string.IsNullOrWhiteSpace(version)
? host.Get<HttpSettings>("http")
: (version.Equals("2.0", StringComparison.CurrentCultureIgnoreCase)
? host.Get<HttpSettings>("extensions:http")
: host.Get<HttpSettings>("http"));
}
private void SetOpenApiInfo()
{
this.HostSettings.ThrowIfNullOrDefault();
this.OpenApiSettingsJsonPath.ThrowIfNullOrWhiteSpace();
this.LocalSettingsJsonPath.ThrowIfNullOrWhiteSpace();
var openApiInfo = this.HostSettings.Get<OpenApiInfo>("openApi:info");
if (this.IsValidOpenApiInfo(openApiInfo))
{
this.OpenApiInfo = openApiInfo;
return;
}
if (File.Exists(this.OpenApiSettingsJsonPath))
{
var openapiSettings = File.ReadAllText(this.OpenApiSettingsJsonPath, Encoding.UTF8);
openApiInfo = JsonConvert.DeserializeObject<OpenApiSettings>(openapiSettings).Info;
if (this.IsValidOpenApiInfo(openApiInfo))
{
this.OpenApiInfo = openApiInfo;
return;
}
}
var localSettings = new ConfigurationBuilder()
.SetBasePath(this.LocalSettingsJsonPath.Replace("local.settings.json", ""))
.AddJsonFile("local.settings.json")
.Build();
openApiInfo = new OpenApiInfo()
{
Version = localSettings.GetValue<string>("Values:OpenApi__Info__Version"),
Title = localSettings.GetValue<string>("Values:OpenApi__Info__Title"),
Description = localSettings.GetValue<string>("Values:OpenApi__Info__Description"),
TermsOfService = new Uri(localSettings.GetValue<string>("Values:OpenApi__Info__TermsOfService")),
Contact = new OpenApiContact()
{
Name = localSettings.GetValue<string>("Values:OpenApi__Info__Contact__Name"),
Email = localSettings.GetValue<string>("Values:OpenApi__Info__Contact__Email"),
Url = new Uri(localSettings.GetValue<string>("Values:OpenApi__Info__Contact__Url")),
},
License = new OpenApiLicense()
{
Name = localSettings.GetValue<string>("Values:OpenApi__Info__License__Name"),
Url = new Uri(localSettings.GetValue<string>("Values:OpenApi__Info__License__Url")),
}
};
this.OpenApiInfo = openApiInfo;
}
private bool IsValidOpenApiInfo(OpenApiInfo openApiInfo)
{
openApiInfo.ThrowIfNullOrDefault();
return !openApiInfo.IsNullOrDefault() && !openApiInfo.Version.IsNullOrDefault() && !openApiInfo.Title.IsNullOrWhiteSpace();
}
}
}

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

@ -0,0 +1,10 @@
const fs = require('fs');
const path = require('path');
const readMeSrc = path.resolve(__dirname, '..', '..', '..', '..', 'docs', 'openapi-cli.md');
const readMeDest = path.resolve(__dirname, '..', 'README.md');
fs.copyFile(readMeSrc, readMeDest, (err) => {
if (err) throw err;
console.log('Copied openapi-cli.md from the docs directory.');
});

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

@ -0,0 +1,82 @@
#! /usr/bin/env node
const unzipper = require('unzipper');
const url = require('url');
const HttpsProxyAgent = require('https-proxy-agent');
const https = require('https');
const version = require('../package.json').version;
const chalk = require('chalk');
const path = require('path');
const fs = require('fs');
const rimraf = require('rimraf');
const glob = require('glob');
const execSync = require('child_process').execSync;
const ProgressBar = require('progress');
const os = require('os');
const args = process.argv;
function getPath() {
const bin = path.resolve(path.join(path.dirname(__filename), '..', 'bin'));
if (fs.existsSync(bin)) {
rimraf.sync(bin);
}
return bin
}
let platform = '';
if (os.platform() === 'win32') {
platform = 'win-x64';
} else if (os.platform() === 'darwin') {
platform = 'osx-x64';
} else if (os.platform() === 'linux') {
platform = 'linux-x64';
} else {
throw Error('platform ' + os.platform() + ' isn\'t supported');
}
const endpoint = 'https://functionscdn.azureedge.net/public/' + version + '/Azure.Functions.Cli.' + platform + '.' + version + '.zip';
console.log('attempting to GET %j', endpoint);
const options = url.parse(endpoint);
// npm config preceed system environment
// https://github.com/npm/npm/blob/19397ad523434656af3d3765e80e22d7e6305f48/lib/config/reg-client.js#L7-L8
// https://github.com/request/request/blob/b12a6245d9acdb1e13c6486d427801e123fdafae/lib/getProxyFromURI.js#L66-L71
const proxy = process.env.npm_config_https_proxy ||
process.env.npm_config_proxy ||
process.env.HTTPS_PROXY ||
process.env.https_proxy ||
process.env.HTTP_PROXY ||
process.env.http_proxy;
if (proxy) {
console.log('using proxy server %j', proxy);
options.agent = new HttpsProxyAgent(proxy);
}
https.get(options, response => {
const bar = new ProgressBar('[:bar] Downloading Azure Functions Core Tools', {
total: Number(response.headers['content-length']),
width: 18
});
if (response.statusCode === 200) {
const installPath = getPath();
response.on('data', data => bar.tick(data.length));
const unzipStream = unzipper.Extract({ path: installPath })
.on('close', () => {
if (os.platform() === 'linux' || os.platform() === 'darwin') {
fs.chmodSync(`${installPath}/azfuncopenapi`, 0o755);
}
});
response.pipe(unzipStream);
} else {
console.error(chalk.red('Error downloading zip file from ' + endpoint));
console.error(chalk.red('Expected: 200, Actual: ' + response.statusCode));
process.exit(1);
}
})
.on('error', err => {
console.error(chalk.red(err));
process.exit(1);
});

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

@ -0,0 +1,21 @@
#! /usr/bin/env node
const path = require('path');
const fs = require('fs');
const spawn = require('child_process').spawn;
const fork = require('child_process').fork;
const commandExists = require('command-exists');
const args = process.argv;
function main() {
const bin = path.resolve(path.join(path.dirname(__filename), '..', 'bin'));
const funcProc = spawn(bin + '/azfuncopenapi', args.slice(2), {
stdio: [process.stdin, process.stdout, process.stderr, 'pipe']
});
funcProc.on('exit', code => {
process.exit(code);
});
}
main();

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

@ -0,0 +1,47 @@
{
"name": "azure-functions-openapi-tools",
"version": "0.8.0",
"description": "This handles Open API documents from Azure Functions without having to run the function app",
"author": "Aliencube Community",
"license": "MIT",
"preferGlobal": true,
"keywords": [
"azure-functions",
"cli",
"openapi",
"swagger"
],
"homepage": "https://github.com/aliencube/AzureFunctions.Extensions",
"bugs": {
"url": "https://github.com/aliencube/AzureFunctions.Extensions/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/aliencube/AzureFunctions.Extensions.git"
},
"scripts": {
"postinstall": "node lib/install.js",
"prepublishOnly": "node lib/copy-metadata.js"
},
"bin": {
"azfuncopenapi": "lib/main.js"
},
"os": [
"win32",
"darwin",
"linux"
],
"engines": {
"node": ">=6.9.1"
},
"dependencies": {
"chalk": "3.0.0",
"command-exists": "1.2.8",
"glob": "7.1.6",
"https-proxy-agent": "5.0.0",
"progress": "2.0.3",
"rimraf": "3.0.2",
"tmp": "0.1.0",
"unzipper": "0.10.10"
}
}

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

@ -0,0 +1,25 @@
using System;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes
{
/// <summary>
/// This represents the attribute entity for enums.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)]
public class DisplayAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="DisplayAttribute"/> class.
/// </summary>
/// <param name="name">The display name.</param>
public DisplayAttribute(string name)
{
this.Name = name ?? throw new ArgumentNullException(nameof(name));
}
/// <summary>
/// Gets the display name.
/// </summary>
public virtual string Name { get; }
}
}

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

@ -0,0 +1,12 @@
using System;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes
{
/// <summary>
/// This represents the attribute entity for HTTP triggers to be excluded for rendering.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class OpenApiIgnoreAttribute : Attribute
{
}
}

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

@ -0,0 +1,49 @@
using System;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes
{
/// <summary>
/// This represents the attribute entity for HTTP triggers to define Open API operation.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class OpenApiOperationAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="OpenApiOperationAttribute"/> class.
/// </summary>
/// <param name="operationId">Operation ID.</param>
/// <param name="tags">List of tags.</param>
public OpenApiOperationAttribute(string operationId = null, params string[] tags)
{
this.OperationId = operationId;
this.Tags = tags;
}
/// <summary>
/// Gets the operation ID.
/// </summary>
public virtual string OperationId { get; }
/// <summary>
/// Gets the list of tags.
/// </summary>
public virtual string[] Tags { get; }
/// <summary>
/// Gets or sets the summary.
/// </summary>
public virtual string Summary { get; set; }
/// <summary>
/// Gets or sets the description.
/// </summary>
public virtual string Description { get; set; }
/// <summary>
/// Gets or sets the <see cref="OpenApiVisibilityType"/> value. Default is <see cref="OpenApiVisibilityType.Undefined"/>.
/// </summary>
public virtual OpenApiVisibilityType Visibility { get; set; } = OpenApiVisibilityType.Undefined;
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше