From 46366ace7f039b11c189a761cc8aa73d4666efb5 Mon Sep 17 00:00:00 2001 From: Tracy Boehrer Date: Tue, 13 Aug 2019 13:53:58 -0500 Subject: [PATCH 1/3] Added servlet-echo and spring-echo sample bots. --- pom.xml | 2 + samples/servlet-echo/LICENSE | 21 + samples/servlet-echo/README.md | 68 +++ .../new-rg-parameters.json | 42 ++ .../preexisting-rg-parameters.json | 39 ++ .../template-with-new-rg.json | 191 ++++++++ .../template-with-preexisting-rg.json | 158 +++++++ samples/servlet-echo/pom.xml | 178 ++++++++ .../bot/sample/servlet/EchoServlet.java | 113 +++++ .../src/main/resources/application.properties | 2 + samples/spring-echo/LICENSE | 21 + samples/spring-echo/README.md | 90 ++++ samples/spring-echo/bin/LICENSE | 21 + samples/spring-echo/bin/README.md | 90 ++++ .../new-rg-parameters.json | 42 ++ .../preexisting-rg-parameters.json | 39 ++ .../template-with-new-rg.json | 191 ++++++++ .../template-with-preexisting-rg.json | 158 +++++++ samples/spring-echo/bin/pom.xml | 191 ++++++++ .../src/main/resources/application.properties | 2 + .../bin/src/main/webapp/META-INF/MANIFEST.MF | 3 + .../bin/src/main/webapp/WEB-INF/web.xml | 12 + .../bin/src/main/webapp/index.html | 418 ++++++++++++++++++ .../new-rg-parameters.json | 42 ++ .../preexisting-rg-parameters.json | 39 ++ .../template-with-new-rg.json | 191 ++++++++ .../template-with-preexisting-rg.json | 158 +++++++ samples/spring-echo/pom.xml | 200 +++++++++ .../bot/sample/spring/Application.java | 11 + .../bot/sample/spring/BotController.java | 85 ++++ .../src/main/resources/application.properties | 2 + .../src/main/webapp/META-INF/MANIFEST.MF | 3 + .../src/main/webapp/WEB-INF/web.xml | 12 + .../spring-echo/src/main/webapp/index.html | 418 ++++++++++++++++++ .../bot/sample/spring/ApplicationTests.java | 16 + 35 files changed, 3269 insertions(+) create mode 100644 samples/servlet-echo/LICENSE create mode 100644 samples/servlet-echo/README.md create mode 100644 samples/servlet-echo/deploymentTemplates/new-rg-parameters.json create mode 100644 samples/servlet-echo/deploymentTemplates/preexisting-rg-parameters.json create mode 100644 samples/servlet-echo/deploymentTemplates/template-with-new-rg.json create mode 100644 samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg.json create mode 100644 samples/servlet-echo/pom.xml create mode 100644 samples/servlet-echo/src/main/java/com/microsoft/bot/sample/servlet/EchoServlet.java create mode 100644 samples/servlet-echo/src/main/resources/application.properties create mode 100644 samples/spring-echo/LICENSE create mode 100644 samples/spring-echo/README.md create mode 100644 samples/spring-echo/bin/LICENSE create mode 100644 samples/spring-echo/bin/README.md create mode 100644 samples/spring-echo/bin/deploymentTemplates/new-rg-parameters.json create mode 100644 samples/spring-echo/bin/deploymentTemplates/preexisting-rg-parameters.json create mode 100644 samples/spring-echo/bin/deploymentTemplates/template-with-new-rg.json create mode 100644 samples/spring-echo/bin/deploymentTemplates/template-with-preexisting-rg.json create mode 100644 samples/spring-echo/bin/pom.xml create mode 100644 samples/spring-echo/bin/src/main/resources/application.properties create mode 100644 samples/spring-echo/bin/src/main/webapp/META-INF/MANIFEST.MF create mode 100644 samples/spring-echo/bin/src/main/webapp/WEB-INF/web.xml create mode 100644 samples/spring-echo/bin/src/main/webapp/index.html create mode 100644 samples/spring-echo/deploymentTemplates/new-rg-parameters.json create mode 100644 samples/spring-echo/deploymentTemplates/preexisting-rg-parameters.json create mode 100644 samples/spring-echo/deploymentTemplates/template-with-new-rg.json create mode 100644 samples/spring-echo/deploymentTemplates/template-with-preexisting-rg.json create mode 100644 samples/spring-echo/pom.xml create mode 100644 samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java create mode 100644 samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/BotController.java create mode 100644 samples/spring-echo/src/main/resources/application.properties create mode 100644 samples/spring-echo/src/main/webapp/META-INF/MANIFEST.MF create mode 100644 samples/spring-echo/src/main/webapp/WEB-INF/web.xml create mode 100644 samples/spring-echo/src/main/webapp/index.html create mode 100644 samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java diff --git a/pom.xml b/pom.xml index b2b8edbde..987092737 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,8 @@ libraries/bot-builder libraries/bot-connector samples/bot-connector-sample + samples/servlet-echo + samples/spring-echo diff --git a/samples/servlet-echo/LICENSE b/samples/servlet-echo/LICENSE new file mode 100644 index 000000000..09d2ba6d8 --- /dev/null +++ b/samples/servlet-echo/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Dave Taniguchi + +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. diff --git a/samples/servlet-echo/README.md b/samples/servlet-echo/README.md new file mode 100644 index 000000000..6eea0c93b --- /dev/null +++ b/samples/servlet-echo/README.md @@ -0,0 +1,68 @@ +# Servlet EchoBot + +This demonstrates how to create a Bot using the Bot Framework 4 SDK Preview for Java in Azure. + +This sample is a Java Servlet app and uses the Azure CLI and azure-webapp Maven plugin to deploy. + +## Prerequisites + +- Install [Maven](https://maven.apache.org/) +- An account on [Azure](https://azure.microsoft.com) + +## Deploy the bot to Azure + +As described on [Deploy your bot](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-deploy-az-cli), you will perform the first 4 steps to setup the Azure app, then deploy the code using the azure-webapp Maven plugin. + +### 1. Login to Azure +From a command (or Powershell) prompt in the root of the bot folder, execute: +`az login` + +### 2. Set the subscription +`az account set --subscription ""` + +If you aren't sure which subscription to use for deploying the bot, you can view the list of subscriptions for your account by using `az account list` command. + +### 3. Create an App registration +`az ad app create --display-name "" --password "" --available-to-other-tenants` + +Replace `` and `` with your own values. + +`` is the unique name of your bot. +`` is a minimum 16 character password for you bot. + +Record the `appid` from the returned JSON + +### 4. Create the Azure resources +Replace the values for ``, ``, ``, and `` in the following commands: + +#### To a new Resource Group +`az deployment create --name "echoBotDeploy" --location "westus" --template-file ".\deploymentTemplates\template-with-new-rg.json" --parameters groupName="" botId="" appId="" appSecret=""` + +#### To an existing Resource Group +`az group deployment create --name "echoBotDeploy" --resource-group "" --template-file ".\deploymentTemplates\template-with-preexisting-rg.json" --parameters botId="" appId="" appSecret=""` + +### 5. Update the pom.xml +In pom.xml update the following nodes under azure-webapp-maven-plugin +- `resourceGroup` using the `` used above +- `appName` using the `` used above + +### 6. Update app id and password +In src/main/resources/application.properties update + - `MicrosoftAppPassword` with the appsecret value + - `MicrosoftAppId` with the appid from the first step + +### 7. Deploy the code +- Execute `mvn clean package` +- Execute `mvn azure-webapp:deploy` + +If the deployment is successful, you will be able to test it via "Test in Web Chat" from the Azure Portal using the "Bot Channel Registration" for the bot. + +After the bot is deployed, you only need to execute #7 if you make changes to the bot. + + +## Reference + +[Maven Plugin for Azure App Service](https://docs.microsoft.com/en-us/java/api/overview/azure/maven/azure-webapp-maven-plugin/readme?view=azure-java-stable) + +[Azure for Java cloud developers](https://docs.microsoft.com/en-us/azure/java/?view=azure-java-stable) + diff --git a/samples/servlet-echo/deploymentTemplates/new-rg-parameters.json b/samples/servlet-echo/deploymentTemplates/new-rg-parameters.json new file mode 100644 index 000000000..ead339093 --- /dev/null +++ b/samples/servlet-echo/deploymentTemplates/new-rg-parameters.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "value": "" + }, + "groupName": { + "value": "" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/servlet-echo/deploymentTemplates/preexisting-rg-parameters.json b/samples/servlet-echo/deploymentTemplates/preexisting-rg-parameters.json new file mode 100644 index 000000000..b6f5114fc --- /dev/null +++ b/samples/servlet-echo/deploymentTemplates/preexisting-rg-parameters.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appServicePlanLocation": { + "value": "" + }, + "existingAppServicePlan": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/servlet-echo/deploymentTemplates/template-with-new-rg.json b/samples/servlet-echo/deploymentTemplates/template-with-new-rg.json new file mode 100644 index 000000000..dcd6260a5 --- /dev/null +++ b/samples/servlet-echo/deploymentTemplates/template-with-new-rg.json @@ -0,0 +1,191 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "F0", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "newAppServicePlanLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The location of the App Service Plan. Defaults to \"westus\"." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "resourcesLocation": "[deployment().location]", + "effectiveGroupLocation": "[if(empty(parameters('groupLocation')), variables('resourcesLocation'), parameters('groupLocation'))]", + "effectivePlanLocation": "[if(empty(parameters('newAppServicePlanLocation')), variables('resourcesLocation'), parameters('newAppServicePlanLocation'))]", + "appServicePlanName": "[if(empty(parameters('newAppServicePlanName')), concat(parameters('botId'), 'ServicePlan'), parameters('newAppServicePlanName'))]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[variables('effectiveGroupLocation')]", + "properties": { + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('effectivePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('appServicePlanName')]", + "reserved":true + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg.json b/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg.json new file mode 100644 index 000000000..b790d2bdc --- /dev/null +++ b/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg.json @@ -0,0 +1,158 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "S1", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "existingAppServicePlan": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", + "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", + "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), if(empty(parameters('newAppServicePlanName')),concat(parameters('botId'), 'ServicePlan'),parameters('newAppServicePlanName')))]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), resourceGroup().location, parameters('appServicePlanLocation'))]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingAppServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('servicePlanName')]", + "reserved":true + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2016-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms/', variables('servicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[variables('servicePlanName')]", + "siteConfig": { + "linuxFxVersion": "JAVA|8-jre8", + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ] +} \ No newline at end of file diff --git a/samples/servlet-echo/pom.xml b/samples/servlet-echo/pom.xml new file mode 100644 index 000000000..98b1760e9 --- /dev/null +++ b/samples/servlet-echo/pom.xml @@ -0,0 +1,178 @@ + + + + 4.0.0 + + com.microsoft.bot.sample + bot-servlet-echo + war + 1.0.0 + + ${project.groupId}:${project.artifactId} + http://maven.apache.org + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + + + + + + Bot Framework Development + + Microsoft + https://dev.botframework.com/ + + + + + UTF-8 + false + + + + + javax.servlet + javax.servlet-api + 3.1.0 + + + junit + junit + 4.12 + test + + + com.fasterxml.jackson.module + jackson-module-parameter-names + 2.9.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + 2.9.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.9.2 + + + org.slf4j + slf4j-api + 1.7.26 + + + org.slf4j + slf4j-simple + 1.7.26 + + + com.microsoft.bot + bot-schema + 4.0.0-SNAPSHOT + + + com.microsoft.bot + bot-connector + 4.0.0-SNAPSHOT + + + + + + MyGet + ${repo.url} + + + + + + MyGet + ${repo.url} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + 2.1 + + false + src/main/webapp + + + + com.microsoft.azure + azure-webapp-maven-plugin + 1.7.0 + + V2 + {groupname} + {botname} + + + JAVA_OPTS + -Dserver.port=80 + + + + linux + jre8 + tomcat 9.0 + + + + + ${project.basedir}/target + + *.war + + + + + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.7 + + ../../cobertura-report/servlet-echo-sample + xml + 256m + + true + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.12.0 + + + validate + + check + + + + + + + diff --git a/samples/servlet-echo/src/main/java/com/microsoft/bot/sample/servlet/EchoServlet.java b/samples/servlet-echo/src/main/java/com/microsoft/bot/sample/servlet/EchoServlet.java new file mode 100644 index 000000000..e8547fb03 --- /dev/null +++ b/samples/servlet-echo/src/main/java/com/microsoft/bot/sample/servlet/EchoServlet.java @@ -0,0 +1,113 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.bot.sample.servlet; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.aad.adal4j.AuthenticationException; +import com.microsoft.bot.connector.authentication.ClaimsIdentity; +import com.microsoft.bot.connector.authentication.CredentialProvider; +import com.microsoft.bot.connector.authentication.CredentialProviderImpl; +import com.microsoft.bot.connector.authentication.JwtTokenValidation; +import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials; +import com.microsoft.bot.connector.implementation.ConnectorClientImpl; +import com.microsoft.bot.schema.models.Activity; +import com.microsoft.bot.schema.models.ActivityTypes; +import javax.servlet.*; +import javax.servlet.http.*; +import javax.servlet.annotation.WebServlet; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.CompletableFuture; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This is the Servlet that will receive incoming Channel Activity messages. + */ +@WebServlet(name = "EchoServlet", urlPatterns = "/api/messages") +public class EchoServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(EchoServlet.class.getName()); + + private ObjectMapper objectMapper; + private CredentialProvider credentialProvider; + private MicrosoftAppCredentials credentials; + + @Override + public void init() throws ServletException { + try{ + this.objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .findAndRegisterModules(); + + // Load the application.properties from the classpath + Properties p = new Properties(); + p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties")); + + String appId = p.getProperty("MicrosoftAppId"); + String appPassword = p.getProperty("MicrosoftAppPassword"); + + this.credentialProvider = new CredentialProviderImpl(appId, appPassword); + this.credentials = new MicrosoftAppCredentials(appId, appPassword); + } + catch(IOException ioe){ + throw new ServletException(ioe); + } + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + final Activity activity = getActivity(request); + String authHeader = request.getHeader("Authorization"); + + CompletableFuture authenticateRequest = JwtTokenValidation.authenticateRequest(activity, authHeader, credentialProvider); + authenticateRequest.thenRunAsync(() -> { + if (activity.type().equals(ActivityTypes.MESSAGE)) { + // reply activity with the same text + ConnectorClientImpl connector = new ConnectorClientImpl(activity.serviceUrl(), this.credentials); + connector.conversations().sendToConversation(activity.conversation().id(), + new Activity() + .withType(ActivityTypes.MESSAGE) + .withText("Echo: " + activity.text()) + .withRecipient(activity.from()) + .withFrom(activity.recipient()) + ); + } + }); + } catch (AuthenticationException ex) { + response.setStatus(401); + LOGGER.log(Level.WARNING, "Auth failed!", ex); + } catch (Exception ex) { + response.setStatus(500); + LOGGER.log(Level.WARNING, "Execution failed", ex); + } + } + + // Creates an Activity object from the request + private Activity getActivity(HttpServletRequest request) throws IOException, JsonParseException, JsonMappingException { + String body = getRequestBody(request); + LOGGER.log(Level.INFO, body); + return objectMapper.readValue(body, Activity.class); + } + + private String getRequestBody(HttpServletRequest request) throws IOException { + StringBuilder buffer = new StringBuilder(); + InputStream stream = request.getInputStream(); + int rByte; + while ((rByte = stream.read()) != -1) { + buffer.append((char)rByte); + } + stream.close(); + if (buffer.length() > 0) { + return buffer.toString(); + } + return ""; + } +} diff --git a/samples/servlet-echo/src/main/resources/application.properties b/samples/servlet-echo/src/main/resources/application.properties new file mode 100644 index 000000000..660828e3e --- /dev/null +++ b/samples/servlet-echo/src/main/resources/application.properties @@ -0,0 +1,2 @@ +MicrosoftAppId= +MicrosoftAppPassword= \ No newline at end of file diff --git a/samples/spring-echo/LICENSE b/samples/spring-echo/LICENSE new file mode 100644 index 000000000..09d2ba6d8 --- /dev/null +++ b/samples/spring-echo/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Dave Taniguchi + +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. diff --git a/samples/spring-echo/README.md b/samples/spring-echo/README.md new file mode 100644 index 000000000..c46553f5c --- /dev/null +++ b/samples/spring-echo/README.md @@ -0,0 +1,90 @@ +# Spring Boot EchoBot + +This demonstrates how to create a Bot using the Bot Framework 4 SDK Preview for Java in Azure. + +This sample is a Spring Boot app and uses the Azure CLI and azure-webapp Maven plugin to deploy to Azure. + +## Prerequisites + +- Java 1.8+ +- Install [Maven](https://maven.apache.org/) +- An account on [Azure](https://azure.microsoft.com) if you want to deploy to Azure. + +## To try this sample locally +- From the root of this project folder: + - Build the sample using `mvn package` + - Run it by using `java -jar .\target\springechobot-sample.jar` + +- Test the bot using Bot Framework Emulator + + [Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel. + + - Install the Bot Framework Emulator version 4.3.0 or greater from [here](https://github.com/Microsoft/BotFramework-Emulator/releases) + + - Connect to the bot using Bot Framework Emulator + + - Launch Bot Framework Emulator + - File -> Open Bot + - Enter a Bot URL of `http://localhost:8080/api/messages` + +## Deploy the bot to Azure + +As described on [Deploy your bot](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-deploy-az-cli), you will perform the first 4 steps to setup the Azure app, then deploy the code using the azure-webapp Maven plugin. + +### 1. Login to Azure +From a command (or Powershell) prompt in the root of the bot folder, execute: +`az login` + +### 2. Set the subscription +`az account set --subscription ""` + +If you aren't sure which subscription to use for deploying the bot, you can view the list of subscriptions for your account by using `az account list` command. + +### 3. Create an App registration +`az ad app create --display-name "" --password "" --available-to-other-tenants` + +Replace `` and `` with your own values. + +`` is the unique name of your bot. +`` is a minimum 16 character password for your bot. + +Record the `appid` from the returned JSON + +### 4. Create the Azure resources +Replace the values for ``, ``, ``, and `` in the following commands: + +#### To a new Resource Group +`az deployment create --name "echoBotDeploy" --location "westus" --template-file ".\deploymentTemplates\template-with-new-rg.json" --parameters groupName="" botId="" appId="" appSecret=""` + +#### To an existing Resource Group +`az group deployment create --name "echoBotDeploy" --resource-group "" --template-file ".\deploymentTemplates\template-with-preexisting-rg.json" --parameters botId="" appId="" appSecret=""` + +### 5. Update the pom.xml +In pom.xml update the following nodes under azure-webapp-maven-plugin +- `resourceGroup` using the `` used above +- `appName` using the `` used above + +### 6. Update app id and password +In src/main/resources/application.properties update + - `MicrosoftAppPassword` with the botsecret value + - `MicrosoftAppId` with the appid from the first step + +### 7. Deploy the code +- Execute `mvn clean package` +- Execute `mvn azure-webapp:deploy` + +If the deployment is successful, you will be able to test it via "Test in Web Chat" from the Azure Portal using the "Bot Channel Registration" for the bot. + +After the bot is deployed, you only need to execute #7 if you make changes to the bot. + + +## Further reading + +- [Maven Plugin for Azure App Service](https://docs.microsoft.com/en-us/java/api/overview/azure/maven/azure-webapp-maven-plugin/readme?view=azure-java-stable) +- [Spring Boot](https://spring.io/projects/spring-boot) +- [Azure for Java cloud developers](https://docs.microsoft.com/en-us/azure/java/?view=azure-java-stable) +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) diff --git a/samples/spring-echo/bin/LICENSE b/samples/spring-echo/bin/LICENSE new file mode 100644 index 000000000..09d2ba6d8 --- /dev/null +++ b/samples/spring-echo/bin/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Dave Taniguchi + +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. diff --git a/samples/spring-echo/bin/README.md b/samples/spring-echo/bin/README.md new file mode 100644 index 000000000..c46553f5c --- /dev/null +++ b/samples/spring-echo/bin/README.md @@ -0,0 +1,90 @@ +# Spring Boot EchoBot + +This demonstrates how to create a Bot using the Bot Framework 4 SDK Preview for Java in Azure. + +This sample is a Spring Boot app and uses the Azure CLI and azure-webapp Maven plugin to deploy to Azure. + +## Prerequisites + +- Java 1.8+ +- Install [Maven](https://maven.apache.org/) +- An account on [Azure](https://azure.microsoft.com) if you want to deploy to Azure. + +## To try this sample locally +- From the root of this project folder: + - Build the sample using `mvn package` + - Run it by using `java -jar .\target\springechobot-sample.jar` + +- Test the bot using Bot Framework Emulator + + [Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel. + + - Install the Bot Framework Emulator version 4.3.0 or greater from [here](https://github.com/Microsoft/BotFramework-Emulator/releases) + + - Connect to the bot using Bot Framework Emulator + + - Launch Bot Framework Emulator + - File -> Open Bot + - Enter a Bot URL of `http://localhost:8080/api/messages` + +## Deploy the bot to Azure + +As described on [Deploy your bot](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-deploy-az-cli), you will perform the first 4 steps to setup the Azure app, then deploy the code using the azure-webapp Maven plugin. + +### 1. Login to Azure +From a command (or Powershell) prompt in the root of the bot folder, execute: +`az login` + +### 2. Set the subscription +`az account set --subscription ""` + +If you aren't sure which subscription to use for deploying the bot, you can view the list of subscriptions for your account by using `az account list` command. + +### 3. Create an App registration +`az ad app create --display-name "" --password "" --available-to-other-tenants` + +Replace `` and `` with your own values. + +`` is the unique name of your bot. +`` is a minimum 16 character password for your bot. + +Record the `appid` from the returned JSON + +### 4. Create the Azure resources +Replace the values for ``, ``, ``, and `` in the following commands: + +#### To a new Resource Group +`az deployment create --name "echoBotDeploy" --location "westus" --template-file ".\deploymentTemplates\template-with-new-rg.json" --parameters groupName="" botId="" appId="" appSecret=""` + +#### To an existing Resource Group +`az group deployment create --name "echoBotDeploy" --resource-group "" --template-file ".\deploymentTemplates\template-with-preexisting-rg.json" --parameters botId="" appId="" appSecret=""` + +### 5. Update the pom.xml +In pom.xml update the following nodes under azure-webapp-maven-plugin +- `resourceGroup` using the `` used above +- `appName` using the `` used above + +### 6. Update app id and password +In src/main/resources/application.properties update + - `MicrosoftAppPassword` with the botsecret value + - `MicrosoftAppId` with the appid from the first step + +### 7. Deploy the code +- Execute `mvn clean package` +- Execute `mvn azure-webapp:deploy` + +If the deployment is successful, you will be able to test it via "Test in Web Chat" from the Azure Portal using the "Bot Channel Registration" for the bot. + +After the bot is deployed, you only need to execute #7 if you make changes to the bot. + + +## Further reading + +- [Maven Plugin for Azure App Service](https://docs.microsoft.com/en-us/java/api/overview/azure/maven/azure-webapp-maven-plugin/readme?view=azure-java-stable) +- [Spring Boot](https://spring.io/projects/spring-boot) +- [Azure for Java cloud developers](https://docs.microsoft.com/en-us/azure/java/?view=azure-java-stable) +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) diff --git a/samples/spring-echo/bin/deploymentTemplates/new-rg-parameters.json b/samples/spring-echo/bin/deploymentTemplates/new-rg-parameters.json new file mode 100644 index 000000000..ead339093 --- /dev/null +++ b/samples/spring-echo/bin/deploymentTemplates/new-rg-parameters.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "value": "" + }, + "groupName": { + "value": "" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/spring-echo/bin/deploymentTemplates/preexisting-rg-parameters.json b/samples/spring-echo/bin/deploymentTemplates/preexisting-rg-parameters.json new file mode 100644 index 000000000..b6f5114fc --- /dev/null +++ b/samples/spring-echo/bin/deploymentTemplates/preexisting-rg-parameters.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appServicePlanLocation": { + "value": "" + }, + "existingAppServicePlan": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/spring-echo/bin/deploymentTemplates/template-with-new-rg.json b/samples/spring-echo/bin/deploymentTemplates/template-with-new-rg.json new file mode 100644 index 000000000..dcd6260a5 --- /dev/null +++ b/samples/spring-echo/bin/deploymentTemplates/template-with-new-rg.json @@ -0,0 +1,191 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "F0", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "newAppServicePlanLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The location of the App Service Plan. Defaults to \"westus\"." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "resourcesLocation": "[deployment().location]", + "effectiveGroupLocation": "[if(empty(parameters('groupLocation')), variables('resourcesLocation'), parameters('groupLocation'))]", + "effectivePlanLocation": "[if(empty(parameters('newAppServicePlanLocation')), variables('resourcesLocation'), parameters('newAppServicePlanLocation'))]", + "appServicePlanName": "[if(empty(parameters('newAppServicePlanName')), concat(parameters('botId'), 'ServicePlan'), parameters('newAppServicePlanName'))]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[variables('effectiveGroupLocation')]", + "properties": { + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('effectivePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('appServicePlanName')]", + "reserved":true + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/spring-echo/bin/deploymentTemplates/template-with-preexisting-rg.json b/samples/spring-echo/bin/deploymentTemplates/template-with-preexisting-rg.json new file mode 100644 index 000000000..b790d2bdc --- /dev/null +++ b/samples/spring-echo/bin/deploymentTemplates/template-with-preexisting-rg.json @@ -0,0 +1,158 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "S1", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "existingAppServicePlan": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", + "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", + "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), if(empty(parameters('newAppServicePlanName')),concat(parameters('botId'), 'ServicePlan'),parameters('newAppServicePlanName')))]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), resourceGroup().location, parameters('appServicePlanLocation'))]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingAppServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('servicePlanName')]", + "reserved":true + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2016-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms/', variables('servicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[variables('servicePlanName')]", + "siteConfig": { + "linuxFxVersion": "JAVA|8-jre8", + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ] +} \ No newline at end of file diff --git a/samples/spring-echo/bin/pom.xml b/samples/spring-echo/bin/pom.xml new file mode 100644 index 000000000..880c0e973 --- /dev/null +++ b/samples/spring-echo/bin/pom.xml @@ -0,0 +1,191 @@ + + + + 4.0.0 + + com.microsoft.bot.connector.sample + spring-echobot + sample + jar + + ${project.groupId}:${project.artifactId} + http://maven.apache.org + + + org.springframework.boot + spring-boot-starter-parent + 2.1.7.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + com.microsoft.bot.sample.spring.Application + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + 4.12 + test + + + com.microsoft.bot.schema + botbuilder-schema + 4.0.0-SNAPSHOT + + + com.microsoft.bot.connector + bot-connector + 4.0.0-SNAPSHOT + + + com.fasterxml.jackson.module + jackson-module-parameter-names + 2.9.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + 2.9.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.9.2 + + + + + + MyGet + ${repo.url} + + + + + + MyGet + ${repo.url} + + + + + + + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + maven-war-plugin + 3.2.3 + + src/main/webapp + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + com.microsoft.bot.sample.spring.Application + + + + + + com.microsoft.azure + azure-webapp-maven-plugin + 1.7.0 + + V2 + {groupname} + {botname} + + + JAVA_OPTS + -Dserver.port=80 + + + + linux + jre8 + jre8 + + + + + ${project.basedir}/target + + *.jar + + + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.3.0 + + yourcoverallsprojectrepositorytoken + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.7 + + ../../cobertura-report/spring-echo-sample + xml + 256m + + true + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.12.0 + + + validate + + check + + + + + + + + + + org.apache.maven.plugins + maven-pmd-plugin + + + + diff --git a/samples/spring-echo/bin/src/main/resources/application.properties b/samples/spring-echo/bin/src/main/resources/application.properties new file mode 100644 index 000000000..a695b3bf0 --- /dev/null +++ b/samples/spring-echo/bin/src/main/resources/application.properties @@ -0,0 +1,2 @@ +MicrosoftAppId= +MicrosoftAppPassword= diff --git a/samples/spring-echo/bin/src/main/webapp/META-INF/MANIFEST.MF b/samples/spring-echo/bin/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 000000000..254272e1c --- /dev/null +++ b/samples/spring-echo/bin/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/samples/spring-echo/bin/src/main/webapp/WEB-INF/web.xml b/samples/spring-echo/bin/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..383c19004 --- /dev/null +++ b/samples/spring-echo/bin/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,12 @@ + + + dispatcher + + org.springframework.web.servlet.DispatcherServlet + + + contextConfigLocation + /WEB-INF/spring/dispatcher-config.xml + + 1 + \ No newline at end of file diff --git a/samples/spring-echo/bin/src/main/webapp/index.html b/samples/spring-echo/bin/src/main/webapp/index.html new file mode 100644 index 000000000..40b74c007 --- /dev/null +++ b/samples/spring-echo/bin/src/main/webapp/index.html @@ -0,0 +1,418 @@ + + + + + + + EchoBot + + + + + +
+
+
+
Spring Boot Bot
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:8080/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + + diff --git a/samples/spring-echo/deploymentTemplates/new-rg-parameters.json b/samples/spring-echo/deploymentTemplates/new-rg-parameters.json new file mode 100644 index 000000000..ead339093 --- /dev/null +++ b/samples/spring-echo/deploymentTemplates/new-rg-parameters.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "value": "" + }, + "groupName": { + "value": "" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/spring-echo/deploymentTemplates/preexisting-rg-parameters.json b/samples/spring-echo/deploymentTemplates/preexisting-rg-parameters.json new file mode 100644 index 000000000..b6f5114fc --- /dev/null +++ b/samples/spring-echo/deploymentTemplates/preexisting-rg-parameters.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "botId": { + "value": "" + }, + "botSku": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appServicePlanLocation": { + "value": "" + }, + "existingAppServicePlan": { + "value": "" + }, + "newWebAppName": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/spring-echo/deploymentTemplates/template-with-new-rg.json b/samples/spring-echo/deploymentTemplates/template-with-new-rg.json new file mode 100644 index 000000000..dcd6260a5 --- /dev/null +++ b/samples/spring-echo/deploymentTemplates/template-with-new-rg.json @@ -0,0 +1,191 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "F0", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "newAppServicePlanLocation": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "The location of the App Service Plan. Defaults to \"westus\"." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "resourcesLocation": "[deployment().location]", + "effectiveGroupLocation": "[if(empty(parameters('groupLocation')), variables('resourcesLocation'), parameters('groupLocation'))]", + "effectivePlanLocation": "[if(empty(parameters('newAppServicePlanLocation')), variables('resourcesLocation'), parameters('newAppServicePlanLocation'))]", + "appServicePlanName": "[if(empty(parameters('newAppServicePlanName')), concat(parameters('botId'), 'ServicePlan'), parameters('newAppServicePlanName'))]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[variables('effectiveGroupLocation')]", + "properties": { + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('effectivePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('appServicePlanName')]", + "reserved":true + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/spring-echo/deploymentTemplates/template-with-preexisting-rg.json b/samples/spring-echo/deploymentTemplates/template-with-preexisting-rg.json new file mode 100644 index 000000000..b790d2bdc --- /dev/null +++ b/samples/spring-echo/deploymentTemplates/template-with-preexisting-rg.json @@ -0,0 +1,158 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"." + } + }, + "botId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." + } + }, + "botSku": { + "defaultValue": "S1", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "P1v2", + "tier": "PremiumV2", + "size": "P1v2", + "family": "Pv2", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "existingAppServicePlan": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "newWebAppName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." + } + } + }, + "variables": { + "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", + "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", + "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), if(empty(parameters('newAppServicePlanName')),concat(parameters('botId'), 'ServicePlan'),parameters('newAppServicePlanName')))]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), resourceGroup().location, parameters('appServicePlanLocation'))]", + "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", + "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", + "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingAppServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('servicePlanName')]", + "reserved":true + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2016-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms/', variables('servicePlanName'))]" + ], + "name": "[variables('webAppName')]", + "properties": { + "name": "[variables('webAppName')]", + "serverFarmId": "[variables('servicePlanName')]", + "siteConfig": { + "linuxFxVersion": "JAVA|8-jre8", + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + } + } + } + }, + { + "apiVersion": "2017-12-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('botId')]", + "location": "global", + "kind": "bot", + "sku": { + "name": "[parameters('botSku')]" + }, + "properties": { + "name": "[parameters('botId')]", + "displayName": "[parameters('botId')]", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "developerAppInsightsApplicationId": null, + "developerAppInsightKey": null, + "publishingCredentials": null, + "storageResourceId": null + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" + ] + } + ] +} \ No newline at end of file diff --git a/samples/spring-echo/pom.xml b/samples/spring-echo/pom.xml new file mode 100644 index 000000000..87b442219 --- /dev/null +++ b/samples/spring-echo/pom.xml @@ -0,0 +1,200 @@ + + + + 4.0.0 + + com.microsoft.bot.sample + bot-spring-echo + sample + jar + + ${project.groupId}:${project.artifactId} + http://maven.apache.org + + + org.springframework.boot + spring-boot-starter-parent + 2.1.7.RELEASE + + + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + + + + + + Bot Framework Development + + Microsoft + https://dev.botframework.com/ + + + + + UTF-8 + UTF-8 + 1.8 + com.microsoft.bot.sample.spring.Application + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + 4.12 + test + + + com.microsoft.bot + bot-schema + 4.0.0-SNAPSHOT + + + com.microsoft.bot + bot-connector + 4.0.0-SNAPSHOT + + + com.fasterxml.jackson.module + jackson-module-parameter-names + 2.9.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + 2.9.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.9.2 + + + + + + MyGet + ${repo.url} + + + + + + MyGet + ${repo.url} + + + + + + + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + maven-war-plugin + 3.2.3 + + src/main/webapp + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + com.microsoft.bot.sample.spring.Application + + + + + + com.microsoft.azure + azure-webapp-maven-plugin + 1.7.0 + + V2 + {groupname} + {botname} + + + JAVA_OPTS + -Dserver.port=80 + + + + linux + jre8 + jre8 + + + + + ${project.basedir}/target + + *.jar + + + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.3.0 + + yourcoverallsprojectrepositorytoken + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.7 + + ../../cobertura-report/spring-echo-sample + xml + 256m + + true + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.12.0 + + + validate + + check + + + + + + + diff --git a/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java b/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java new file mode 100644 index 000000000..1c4475e5c --- /dev/null +++ b/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java @@ -0,0 +1,11 @@ +package com.microsoft.bot.sample.spring; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/BotController.java b/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/BotController.java new file mode 100644 index 000000000..848184f71 --- /dev/null +++ b/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/BotController.java @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.bot.sample.spring; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.PostConstruct; + +import com.microsoft.aad.adal4j.AuthenticationException; +import com.microsoft.bot.connector.authentication.ClaimsIdentity; +import com.microsoft.bot.connector.authentication.CredentialProvider; +import com.microsoft.bot.connector.authentication.CredentialProviderImpl; +import com.microsoft.bot.connector.authentication.JwtTokenValidation; +import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials; +import com.microsoft.bot.connector.implementation.ConnectorClientImpl; +import com.microsoft.bot.schema.models.Activity; +import com.microsoft.bot.schema.models.ActivityTypes; + +import java.util.concurrent.CompletableFuture; + +/** + * This is the controller that will receive incoming Channel Activity messages. + */ +@RestController +public class BotController { + /** The appId from application.properties. */ + @Value("${MicrosoftAppId}") + private String appId; + + /** The app secret from application.properties. */ + @Value("${MicrosoftAppPassword}") + private String appPassword; + + private CredentialProvider _credentialProvider; + private MicrosoftAppCredentials _credentials; + + /** + * Performs post construction initialization for this controller. + * This must be done post construction so that application.properties + * have been loaded. + */ + @PostConstruct + public void init() { + _credentialProvider = new CredentialProviderImpl(appId, appPassword); + _credentials = new MicrosoftAppCredentials(appId, appPassword); + } + + /** + * This will receive incoming Channel Activities. + * + * @param activity + * @param authHeader + * @return + */ + @PostMapping("/api/messages") + public ResponseEntity incoming(@RequestBody Activity activity, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader) { + try { + CompletableFuture authenticateRequest = JwtTokenValidation.authenticateRequest(activity, authHeader, _credentialProvider); + authenticateRequest.thenRunAsync(() -> { + if (activity.type().equals(ActivityTypes.MESSAGE)) { + // reply activity with the same text + ConnectorClientImpl connector = new ConnectorClientImpl(activity.serviceUrl(), _credentials); + connector.conversations().sendToConversation(activity.conversation().id(), + new Activity().withType(ActivityTypes.MESSAGE).withText("Echo: " + activity.text()) + .withRecipient(activity.from()).withFrom(activity.recipient())); + } + }); + } catch (AuthenticationException ex) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } catch (Exception ex) { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + + // send ack to user activity + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } +} diff --git a/samples/spring-echo/src/main/resources/application.properties b/samples/spring-echo/src/main/resources/application.properties new file mode 100644 index 000000000..a695b3bf0 --- /dev/null +++ b/samples/spring-echo/src/main/resources/application.properties @@ -0,0 +1,2 @@ +MicrosoftAppId= +MicrosoftAppPassword= diff --git a/samples/spring-echo/src/main/webapp/META-INF/MANIFEST.MF b/samples/spring-echo/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 000000000..254272e1c --- /dev/null +++ b/samples/spring-echo/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/samples/spring-echo/src/main/webapp/WEB-INF/web.xml b/samples/spring-echo/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..383c19004 --- /dev/null +++ b/samples/spring-echo/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,12 @@ + + + dispatcher + + org.springframework.web.servlet.DispatcherServlet + + + contextConfigLocation + /WEB-INF/spring/dispatcher-config.xml + + 1 + \ No newline at end of file diff --git a/samples/spring-echo/src/main/webapp/index.html b/samples/spring-echo/src/main/webapp/index.html new file mode 100644 index 000000000..40b74c007 --- /dev/null +++ b/samples/spring-echo/src/main/webapp/index.html @@ -0,0 +1,418 @@ + + + + + + + EchoBot + + + + + +
+
+
+
Spring Boot Bot
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:8080/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + + diff --git a/samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java b/samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java new file mode 100644 index 000000000..720c62774 --- /dev/null +++ b/samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java @@ -0,0 +1,16 @@ +package com.microsoft.bot.sample.spring; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} From 2d4bad40367e87ac3f1dd29911efe12a41215bb8 Mon Sep 17 00:00:00 2001 From: Tracy Boehrer Date: Wed, 14 Aug 2019 08:57:33 -0500 Subject: [PATCH 2/3] Corrected LICENSE files --- samples/servlet-echo/LICENSE | 34 +++++++++++++++++----------------- samples/spring-echo/LICENSE | 34 +++++++++++++++++----------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/samples/servlet-echo/LICENSE b/samples/servlet-echo/LICENSE index 09d2ba6d8..21071075c 100644 --- a/samples/servlet-echo/LICENSE +++ b/samples/servlet-echo/LICENSE @@ -1,21 +1,21 @@ -MIT License + MIT License -Copyright (c) 2018 Dave Taniguchi + Copyright (c) Microsoft Corporation. All rights reserved. -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: + 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 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. + 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 diff --git a/samples/spring-echo/LICENSE b/samples/spring-echo/LICENSE index 09d2ba6d8..21071075c 100644 --- a/samples/spring-echo/LICENSE +++ b/samples/spring-echo/LICENSE @@ -1,21 +1,21 @@ -MIT License + MIT License -Copyright (c) 2018 Dave Taniguchi + Copyright (c) Microsoft Corporation. All rights reserved. -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: + 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 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. + 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 From e9f816b8b1e544ffe9ff259fbb44dcde59183407 Mon Sep 17 00:00:00 2001 From: Tracy Boehrer Date: Fri, 16 Aug 2019 07:37:59 -0500 Subject: [PATCH 3/3] Added copyright comments --- .../main/java/com/microsoft/bot/sample/spring/Application.java | 3 +++ .../java/com/microsoft/bot/sample/spring/ApplicationTests.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java b/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java index 1c4475e5c..7de5a5e2a 100644 --- a/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java +++ b/samples/spring-echo/src/main/java/com/microsoft/bot/sample/spring/Application.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.microsoft.bot.sample.spring; import org.springframework.boot.SpringApplication; diff --git a/samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java b/samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java index 720c62774..ab13d683f 100644 --- a/samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java +++ b/samples/spring-echo/src/test/java/com/microsoft/bot/sample/spring/ApplicationTests.java @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + package com.microsoft.bot.sample.spring; import org.junit.Test;