diff --git a/.github/workflows/apis-deployment.yaml b/.github/workflows/apis-deployment.yaml new file mode 100644 index 0000000..99bf86b --- /dev/null +++ b/.github/workflows/apis-deployment.yaml @@ -0,0 +1,145 @@ +name: APIs deployment + +on: + push: + branches: + - main + - dev + paths: + - 'apis/**' + - '.github/workflows/apis-deployment.yaml' + workflow_dispatch: + +env: + RG: contoso-${{ github.ref_name }}-rg + APIM_SERVICE: contoso-${{ github.ref_name }}-apim + SA: contoso${{ github.ref_name }}apimsa + +jobs: + + upload-api-descriptors: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Azure Login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Create container for API resources + uses: azure/CLI@v1 + with: + inlineScript: | + for api in `ls apis` + do + az storage container create --name $api --account-name $SA --public-access blob -g $RG + done + + - name: Upload files for each API + uses: azure/CLI@v1 + with: + inlineScript: | + for api in `ls apis` + do + for file in `ls apis/$api | egrep "openapi|policies"` + do + az storage blob upload --overwrite --container-name $api --account-name $SA --file apis/$api/$file + done + done + + generate-arm-templates: + runs-on: ubuntu-latest + needs: upload-api-descriptors + + steps: + - uses: actions/checkout@v2 + + - name: Generate apiconfig with variables + shell: bash + run: | + for api in `ls apis` + do + cat apis/$api/apiconfig.yaml | \ + API_NAME=$api \ + APIM_SERVICE=$APIM_SERVICE \ + SA=$SA \ + envsubst > apis/$api/apiconfig_resolved.yaml + done + + - name: Generate templates for API + uses: addnab/docker-run-action@v3 + with: + image: sancheski/arm-api-creator:0.0.1 + options: -v ${{ github.workspace }}/apis:/app/apis + run: | + for api in `ls /app/apis` + do + dotnet ArmTemplates.dll create --configFile /app/apis/$api/apiconfig_resolved.yaml + done + + - uses: actions/upload-artifact@v3 + with: + name: apis + path: ${{ github.workspace }}/apis + + provision-apis: + runs-on: ubuntu-latest + needs: generate-arm-templates + + steps: + + - uses: actions/download-artifact@v3 + with: + name: apis + path: apis + + - name: Azure Login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Provision API + uses: azure/CLI@v1 + with: + inlineScript: | + for api in `ls apis` + do + az deployment group create --resource-group $RG --template-file apis/$api/generatedtemplates/$api.api.template.json --parameters @apis/$api/generatedtemplates/$api-parameters.json + done + + delete-apis: + runs-on: ubuntu-latest + needs: provision-apis + + steps: + + - uses: actions/checkout@v2 + + - name: Azure Login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Delete API + uses: azure/CLI@v1 + with: + inlineScript: | + ls apis > mustremain.list + echo "Must remain in APIM" + cat mustremain.list + echo "" + az apim api list --service-name $APIM_SERVICE --resource-group $RG \ + -o tsv --query "[].{name:name}" > currentinapim.list + echo "Currently in APIM" + cat currentinapim.list + + for apiToRemove in `diff mustremain.list currentinapim.list \ + | grep -v "+++" | grep -v "\-\-\-" | grep -v "@@" \ + | grep + | awk -F+ '{print $2}'` + do + echo "Deleting API $apiToRemove... not present in git anymore" + az apim api delete -n $APIM_SERVICE -g $RG --api-id $apiToRemove -y + az storage container delete --name $apiToRemove --account-name $SA + done diff --git a/README.md b/README.md index 976fd1c..dab6176 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,135 @@ -# apim-demo-apis -Full APIs with policies and all the content required for a APIM demo +# Azure API demos for APIM + +## Overview + +This repository contains full APIs with policies and all the content required for an APIM demo. + + +## Prerequisites + +This demo requires the following prerequisites: +- Have an APIM previously deployed and configured. You can follow the steps described in this repository: [apim-demo-infra](https://github.com/dsanchor/apim-demo-infra) +- Fork this repository and clone it locally. +- An Azure subscription +- The Azure CLI +- A Service Principal with Contributor rights on the subscription +- Setup credentials in Github Secrets +- Create an storage account and a container for the temporary files used in deployment + +See next sections for instructions on how to set up these prerequisites. + +### Fork and clone the repository + +Fork this repository first. +Then, clone it locally by running the following command in the directory where you want to have the repository: + +```bash +git clone .git +``` + +Move to the *dev* branch: + +```bash +git checkout dev +``` + +We will use the *dev* branch to make changes to the infrastructure which will be deployed as the Develpoment environment. The *main* branch will be used to deploy the Production environment after the changes have been tested in the Development environment, create a PR from the *dev* branch to the *main* branch and merge it. + + +### Azure subscription + +You must have an Azure subscription to deploy this demo. If you don't have an Azure subscription, you can create a [free account](https://azure.microsoft.com/free). + +### Azure CLI + +We will create some prerequired resources with the [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli). + +### Service Principal + +This demo needs a Service Principal to deploy the infrastructure. You can create a Service Principal with the following instructions: + +- Log in to Azure: + +```bash +az login +``` + +- List the available subscriptions: + +```bash +az account list -o table +``` + +- Init the SUBSCRIPTION_ID variable with the subscription ID you want to use: + +```bash +export SUBSCRIPTION_ID= +``` + +- Create the Service Principal with contributor rights on the subscription: + +```bash +az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/$SUBSCRIPTION_ID" --sdk-auth +``` + +Copy the json output of the command and keep it safe for next step (JSON_SP_FOR_GITHUB). + +For details, see the instructions in the [Azure CLI documentation](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest) to create a Service Principal. + +### Github Secrets + +We will create the following secrets in Github Secrets, where all values are the ones you got from the previous step: + +- AZURE_CREDENTIALS = + +### Storage account and container + +We will use a storage account and a container to store temporary data. You can create a storage account and a container with the following instructions: + +- Init the RESOURCE_GROUP variable with the name of the resource group you want to use: + +```bash +export RESOURCE_GROUP= +``` + +- Create the resource group: + +```bash +az group create --name $RESOURCE_GROUP --location westeurope --subscription $SUBSCRIPTION_ID +``` + +- Init the STORAGE_ACCOUNT_NAME variable with the name of the storage account you want to use: + +```bash +export STORAGE_ACCOUNT_NAME= +``` + +- Create the storage account: + +```bash +az storage account create --name $STORAGE_ACCOUNT_NAME --resource-group $RESOURCE_GROUP --location westeurope --sku Standard_LRS --subscription $SUBSCRIPTION_ID +``` + +- Under *.github/workflows/* directory, find the *apis-deployment.yaml* file and modify the name of the variables: + + +RG: Name of the resource group where storage account and apim service is located. + +APIM_SERVICE: Name of the APIM service instance + +SA: Name of the storage account created in previous step + + +# Run the automation + +We have included a [GitHub Action](.github/workflows/apis-deployment.yaml) to run the apis deployment. + +This automation will register APIs inside APIM and its related policies. + +To run the automation, push the changes to the *dev* branch. The automation will run automatically. + +```bash +git add . +git commit -m "Initial commit" +git push origin dev +``` \ No newline at end of file diff --git a/apis/conferenceapi/apiconfig-original.yaml b/apis/conferenceapi/apiconfig-original.yaml new file mode 100644 index 0000000..8a9f51e --- /dev/null +++ b/apis/conferenceapi/apiconfig-original.yaml @@ -0,0 +1,146 @@ +version: 0.0.1 +apimServiceName: contoso-prod-apim +#policy: C:\Users\myUsername\Projects\azure-api-management-devops-example\src\ArmTemplates\Creator\ExampleFiles\XMLPolicies\globalServicePolicy.xml +apiVersionSets: + - id: conferenceAPIv1 + displayName: conferenceAPI + description: a sample public api + versioningScheme: Query + versionQueryName: version +# versionHeaderName: versionHeader +# - id: secondAPIVersionSetID +# displayName: secondSet +# description: another description +# versioningScheme: Header +# versionQueryName: versionQuery +# versionHeaderName: versionHeader +apis: + - name: conferenceAPI + type: http + suffix: conferences + displayName: Conference API + description: A sample public api + serviceUrl: https://conferenceapi.azurewebsites.net + openApiSpec: TODO from blob + openApiSpecFormat: swagger +# policy: TODO from blob +# subscriptionRequired: true + isCurrent: true +# apiVersion: v1 + apiVersionDescription: First api version + apiVersionSetId: conferenceAPIv1 + apiRevision: 1 + apiRevisionDescription: My first revision + # tags: Universe, myTag + # operations: + # addPet: + # policy: C:\Users\myUsername\Projects\azure-api-management-devops-example\src\ArmTemplates\Creator\ExampleFiles\XMLPolicies\operationRateLimit.xml + # deletePet: + # policy: C:\Users\myUsername\Projects\azure-api-management-devops-example\src\ArmTemplates\Creator\ExampleFiles\XMLPolicies\operationRateLimit.xml + # products: starter, platinum + # authenticationSettings: + # oAuth2: +# authorizationServerId: myAuthServer +# scope: myScope +# diagnostic: +# name: applicationinsights +# alwaysLog: allErrors +# loggerId: myAppInsights +# sampling: +# samplingType: fixed +# percentage: 50 +# frontend: +# request: +# headers: +# body: +# bytes: 512 +# response: +# headers: +# body: +# bytes: 512 +# backend: +# request: +# headers: +# body: +# bytes: 512 +# response: +# headers: +# body: +# bytes: 512 +# enableHttpCorrelationHeaders: true +#products: +# - name: platinum +# displayName: Platinum +# description: a test product +# terms: some terms +# subscriptionRequired: true +# approvalRequired: true +# subscriptionsLimit: 1 +# state: notPublished +# policy: C:\Users\myUsername\Projects\azure-api-management-devops-example\src\ArmTemplates\Creator\ExampleFiles\XMLPolicies\productSetBodyBasic.xml +# subscriptions: +# - name: platinum +# primaryKey: a240691f-03fd-4557-a5cb-6e0f65cd976a +# secondaryKey: 032338aa-0076-4379-910c-32ddd42f38a1 +# state: active +# allowTracing: true +#tags: +# - displayName: Universe +#loggers: +# - name: myAppInsights +# loggerType: applicationInsights +# description: a test app insights +# credentials: +# instrumentationKey: 45d4v88-fdfs-4b35-9232-731d82d4d1c6 +# isBuffered: true +#authorizationServers: +# - displayName: myAuthServer +# description: test server +# clientRegistrationEndpoint: https://www.contoso.com/apps +# authorizationEndpoint: https://www.contoso.com/oauth2/auth +# authorizationMethods: +# - GET +# tokenEndpoint: https://www.contoso.com/oauth2/token +# supportState: true +# defaultScope: read write +# grantTypes: +# - authorizationCode +# - implicit +# bearerTokenSendingMethods: +# - authorizationHeader +# clientId: 1 +# clientSecret: 2 +# resourceOwnerUsername: un +# resourceOwnerPassword: pwd +#backends: +# - title: myBackend +# description: description5308 +# url: https://backendname2644/ +# protocol: http +# credentials: +# query: +# sv: +# - xx +# - bb +# header: +# x-my-1: +# - val1 +# - val2 +# authorization: +# scheme: Basic +# parameter: opensesma +# proxy: +# url: http://192.168.1.1:8080 +# username: Contoso\admin +# password: opensesame +# tls: +# validateCertificateChain: false +# validateCertificateName: false +outputLocation: tmpGeneratedTemplates +linked: false +#linkedTemplatesBaseUrl : https://mystorageaccount.blob.core.windows.net/mycontainer +#linkedTemplatesUrlQueryString : ?sv=2018-03-28&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-12-22T23:12:53Z&st=2019-09-09T14:12:53Z&spr=https&sig=uFTldJEYPH888QVzKb7q7eLq0Xt%2Bu35UTqpFGUYo6uc%3D +baseFileName: conference-api +#serviceUrlParameters: +# - apiName: myAPI +# serviceUrl: httpbin.com/myAPI \ No newline at end of file diff --git a/apis/conferenceapi/apiconfig.yaml b/apis/conferenceapi/apiconfig.yaml new file mode 100644 index 0000000..48bd7f7 --- /dev/null +++ b/apis/conferenceapi/apiconfig.yaml @@ -0,0 +1,18 @@ +version: 0.0.1 +apimServiceName: ${APIM_SERVICE} +apis: + - name: ${API_NAME} + type: http + suffix: conferences + displayName: Conference API + openApiSpec: https://${SA}.blob.core.windows.net/${API_NAME}/openapi.json + openApiSpecFormat: swagger + policy: https://${SA}.blob.core.windows.net/${API_NAME}/policies.xml + isCurrent: true +outputLocation: /app/apis/${API_NAME}/generatedtemplates +linked: false +baseFileName: ${API_NAME} +serviceUrlParameters: + - apiName: ${API_NAME} + serviceUrl: https://conferenceapi.azurewebsites.net + diff --git a/apis/conferenceapi/openapi.json b/apis/conferenceapi/openapi.json new file mode 100644 index 0000000..6df0bd9 --- /dev/null +++ b/apis/conferenceapi/openapi.json @@ -0,0 +1,303 @@ +{ + "swagger": "2.0", + "info": { + "title": "Demo Conference API", + "description": "A sample API with information related to a technical conference. The available resources include *Speakers*, *Sessions* and *Topics*. A single write operation is available to provide feedback on a session.", + "version": "2.0.0" + }, + "host": "conferenceapi.azurewebsites.net", + "schemes": [ + "http", + "https" + ], + "securityDefinitions": { + "apiKeyHeader": { + "type": "apiKey", + "name": "Ocp-Apim-Subscription-Key", + "in": "header" + }, + "apiKeyQuery": { + "type": "apiKey", + "name": "subscription-key", + "in": "query" + } + }, + "security": [ + { + "apiKeyHeader": [] + }, + { + "apiKeyQuery": [] + } + ], + "paths": { + "/sessions": { + "get": { + "description": "A list of sessions. Optional parameters work as filters to reduce the listed sessions.", + "operationId": "GetSessions", + "parameters": [ + { + "name": "speakername", + "in": "query", + "type": "string" + }, + { + "name": "dayno", + "in": "query", + "description": "Format - int32.", + "type": "integer" + }, + { + "name": "keyword", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/session/{id}": { + "get": { + "description": "Retreive a representation of a single session by Id", + "operationId": "GetSession", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json", + "text/plain" + ] + } + }, + "/session/{id}/topics": { + "get": { + "operationId": "GetSessionTopics", + "description": "A list of topics covered by a particular session", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/session/{id}/feedback": { + "post": { + "description": "Retreive a representation of a single session by Id", + "operationId": "SubmitSession", + "parameters": [ + { + "$ref": "#/parameters/id" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json", + "text/plain" + ], + "consumes": [ + "text/plain" + ] + } + }, + "/speakers": { + "get": { + "operationId": "GetSpeakers", + "parameters": [ + { + "name": "dayno", + "in": "query", + "description": "Format - int32.", + "type": "integer" + }, + { + "name": "speakername", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/speaker/{id}": { + "get": { + "operationId": "GetSpeaker", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.hal+json", + "text/plain" + ] + } + }, + "/speaker/{id}/sessions": { + "get": { + "operationId": "GetSpeakerSessions", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/speaker/{id}/topics": { + "get": { + "operationId": "GetSpeakerTopics", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/topics": { + "get": { + "operationId": "GetTopics", + "parameters": [ + { + "name": "dayno", + "in": "query", + "required": false, + "description": "Format - int32.", + "type": "integer" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/topic/{id}": { + "get": { + "operationId": "GetTopic", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json" + ] + } + }, + "/topic/{id}/speakers": { + "get": { + "operationId": "GetTopicSpeakers", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/topic/{id}/sessions": { + "get": { + "operationId": "GetTopicSessions", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + } + }, + "parameters": { + "id": { + "name": "id", + "in": "path", + "description": "Format - int32.", + "required": true, + "type": "integer" + } + } +} \ No newline at end of file diff --git a/apis/conferenceapi/policies.xml b/apis/conferenceapi/policies.xml new file mode 100644 index 0000000..a60ad8c --- /dev/null +++ b/apis/conferenceapi/policies.xml @@ -0,0 +1,24 @@ + + + + + + Inbound policy called + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/conferenceapi2/apiconfig.yaml b/apis/conferenceapi2/apiconfig.yaml new file mode 100644 index 0000000..391c26a --- /dev/null +++ b/apis/conferenceapi2/apiconfig.yaml @@ -0,0 +1,17 @@ +version: 0.0.1 +apimServiceName: ${APIM_SERVICE} +apis: + - name: ${API_NAME} + type: http + suffix: conferences2 + displayName: Conference API 2 + openApiSpec: https://${SA}.blob.core.windows.net/${API_NAME}/openapi.json + openApiSpecFormat: swagger + policy: https://${SA}.blob.core.windows.net/${API_NAME}/policies.xml + isCurrent: true +outputLocation: /app/apis/${API_NAME}/generatedtemplates +linked: false +baseFileName: ${API_NAME} +serviceUrlParameters: + - apiName: ${API_NAME} + serviceUrl: https://conferenceapi.azurewebsites.net diff --git a/apis/conferenceapi2/openapi.json b/apis/conferenceapi2/openapi.json new file mode 100644 index 0000000..5354aa6 --- /dev/null +++ b/apis/conferenceapi2/openapi.json @@ -0,0 +1,232 @@ +{ + "swagger": "2.0", + "info": { + "title": "Demo Conference API", + "description": "A sample API with information related to a technical conference. The available resources include *Speakers*, *Sessions* and *Topics*. A single write operation is available to provide feedback on a session.", + "version": "2.0.0" + }, + "host": "conferenceapi.azurewebsites.net", + "schemes": [ + "http", + "https" + ], + "securityDefinitions": { + "apiKeyHeader": { + "type": "apiKey", + "name": "Ocp-Apim-Subscription-Key", + "in": "header" + }, + "apiKeyQuery": { + "type": "apiKey", + "name": "subscription-key", + "in": "query" + } + }, + "security": [ + { + "apiKeyHeader": [] + }, + { + "apiKeyQuery": [] + } + ], + "paths": { + "/sessions": { + "get": { + "description": "A list of sessions. Optional parameters work as filters to reduce the listed sessions.", + "operationId": "GetSessions", + "parameters": [ + { + "name": "speakername", + "in": "query", + "type": "string" + }, + { + "name": "speakername2", + "in": "query", + "type": "string" + }, + { + "name": "speakerlastname", + "in": "query", + "type": "string" + }, + { + "name": "dayno", + "in": "query", + "description": "Format - int32.", + "type": "integer" + }, + { + "name": "keyword", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/session/{id}": { + "get": { + "description": "Retreive a representation of a single session by Id", + "operationId": "GetSession", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json", + "text/plain" + ] + } + }, + "/session/{id}/topics": { + "get": { + "operationId": "GetSessionTopics", + "description": "A list of topics covered by a particular session", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/session/{id}/feedback": { + "post": { + "description": "Retreive a representation of a single session by Id", + "operationId": "SubmitSession", + "parameters": [ + { + "$ref": "#/parameters/id" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json", + "text/plain" + ], + "consumes": [ + "text/plain" + ] + } + }, + "/topics": { + "get": { + "operationId": "GetTopics", + "parameters": [ + { + "name": "dayno", + "in": "query", + "required": false, + "description": "Format - int32.", + "type": "integer" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/topic/{id}": { + "get": { + "operationId": "GetTopic", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json" + ] + } + }, + "/topic/{id}/speakers": { + "get": { + "operationId": "GetTopicSpeakers", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/topic/{id}/sessions": { + "get": { + "operationId": "GetTopicSessions", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + } + }, + "parameters": { + "id": { + "name": "id", + "in": "path", + "description": "Format - int32.", + "required": true, + "type": "integer" + } + } +} diff --git a/apis/conferenceapi2/policies.xml b/apis/conferenceapi2/policies.xml new file mode 100644 index 0000000..5a5f85a --- /dev/null +++ b/apis/conferenceapi2/policies.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apis/conferenceapi3/apiconfig.yaml b/apis/conferenceapi3/apiconfig.yaml new file mode 100644 index 0000000..8fbf812 --- /dev/null +++ b/apis/conferenceapi3/apiconfig.yaml @@ -0,0 +1,17 @@ +version: 0.0.1 +apimServiceName: ${APIM_SERVICE} +apis: + - name: ${API_NAME} + type: http + suffix: conferences3 + displayName: Conference API 3 + openApiSpec: https://${SA}.blob.core.windows.net/${API_NAME}/openapi.json + openApiSpecFormat: swagger + policy: https://${SA}.blob.core.windows.net/${API_NAME}/policies.xml + isCurrent: true +outputLocation: /app/apis/${API_NAME}/generatedtemplates +linked: false +baseFileName: ${API_NAME} +serviceUrlParameters: + - apiName: ${API_NAME} + serviceUrl: https://conferenceapi.azurewebsites.net diff --git a/apis/conferenceapi3/openapi.json b/apis/conferenceapi3/openapi.json new file mode 100644 index 0000000..2d1384e --- /dev/null +++ b/apis/conferenceapi3/openapi.json @@ -0,0 +1,222 @@ +{ + "swagger": "2.0", + "info": { + "title": "Demo Conference API", + "description": "A sample API with information related to a technical conference. The available resources include *Speakers*, *Sessions* and *Topics*. A single write operation is available to provide feedback on a session.", + "version": "2.0.0" + }, + "host": "conferenceapi.azurewebsites.net", + "schemes": [ + "http", + "https" + ], + "securityDefinitions": { + "apiKeyHeader": { + "type": "apiKey", + "name": "Ocp-Apim-Subscription-Key", + "in": "header" + }, + "apiKeyQuery": { + "type": "apiKey", + "name": "subscription-key", + "in": "query" + } + }, + "security": [ + { + "apiKeyHeader": [] + }, + { + "apiKeyQuery": [] + } + ], + "paths": { + "/sessions": { + "get": { + "description": "A list of sessions. Optional parameters work as filters to reduce the listed sessions.", + "operationId": "GetSessions", + "parameters": [ + { + "name": "speakername", + "in": "query", + "type": "string" + }, + { + "name": "dayno", + "in": "query", + "description": "Format - int32.", + "type": "integer" + }, + { + "name": "keyword", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/session/{id}": { + "get": { + "description": "Retreive a representation of a single session by Id", + "operationId": "GetSession", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json", + "text/plain" + ] + } + }, + "/session/{id}/topics": { + "get": { + "operationId": "GetSessionTopics", + "description": "A list of topics covered by a particular session", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/session/{id}/feedback": { + "post": { + "description": "Retreive a representation of a single session by Id", + "operationId": "SubmitSession", + "parameters": [ + { + "$ref": "#/parameters/id" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json", + "text/plain" + ], + "consumes": [ + "text/plain" + ] + } + }, + "/topics": { + "get": { + "operationId": "GetTopics", + "parameters": [ + { + "name": "dayno", + "in": "query", + "required": false, + "description": "Format - int32.", + "type": "integer" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/topic/{id}": { + "get": { + "operationId": "GetTopic", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/hal+json" + ] + } + }, + "/topic/{id}/speakers": { + "get": { + "operationId": "GetTopicSpeakers", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + }, + "/topic/{id}/sessions": { + "get": { + "operationId": "GetTopicSessions", + "parameters": [ + { + "$ref": "#/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "produces": [ + "application/vnd.collection+json" + ] + } + } + }, + "parameters": { + "id": { + "name": "id", + "in": "path", + "description": "Format - int32.", + "required": true, + "type": "integer" + } + } +} \ No newline at end of file diff --git a/apis/conferenceapi3/policies.xml b/apis/conferenceapi3/policies.xml new file mode 100644 index 0000000..5a5f85a --- /dev/null +++ b/apis/conferenceapi3/policies.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file