From b1d549bb68fe3719cf50917a21bd8532da487b1e Mon Sep 17 00:00:00 2001 From: Tracy Boehrer Date: Thu, 5 Sep 2019 14:14:58 -0500 Subject: [PATCH 1/3] EchoServlet is now using Configuration and ChannelProvider to more easily support Gov. --- .../ClasspathPropertiesConfiguration.java | 7 +- samples/servlet-echo/pom.xml | 5 ++ .../bot/sample/servlet/EchoServlet.java | 71 ++++++++++--------- .../src/main/resources/application.properties | 3 +- 4 files changed, 47 insertions(+), 39 deletions(-) diff --git a/libraries/bot-integration-core/src/main/java/com/microsoft/bot/integration/ClasspathPropertiesConfiguration.java b/libraries/bot-integration-core/src/main/java/com/microsoft/bot/integration/ClasspathPropertiesConfiguration.java index af8e5f5ec..7ff52469b 100644 --- a/libraries/bot-integration-core/src/main/java/com/microsoft/bot/integration/ClasspathPropertiesConfiguration.java +++ b/libraries/bot-integration-core/src/main/java/com/microsoft/bot/integration/ClasspathPropertiesConfiguration.java @@ -3,6 +3,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; +import java.io.InputStream; import java.util.Properties; /** @@ -18,10 +19,10 @@ public class ClasspathPropertiesConfiguration implements Configuration { * Loads properties from the 'application.properties' file. */ public ClasspathPropertiesConfiguration() { - try { + try (InputStream input = Thread.currentThread().getContextClassLoader() + .getResourceAsStream("application.properties")) { properties = new Properties(); - properties.load(Thread.currentThread().getContextClassLoader() - .getResourceAsStream("application.properties")); + properties.load(input); } catch (IOException e) { (LoggerFactory.getLogger(ClasspathPropertiesConfiguration.class)).error("Unable to load properties", e); } diff --git a/samples/servlet-echo/pom.xml b/samples/servlet-echo/pom.xml index 03889e664..36f020ab7 100644 --- a/samples/servlet-echo/pom.xml +++ b/samples/servlet-echo/pom.xml @@ -81,6 +81,11 @@ bot-connector 4.0.0-SNAPSHOT + + com.microsoft.bot + bot-integration-core + 4.0.0-SNAPSHOT + 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 index 7d34d05f9..2c8d55874 100644 --- 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 @@ -9,9 +9,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.microsoft.aad.adal4j.AuthenticationException; import com.microsoft.bot.connector.ConnectorClient; -import com.microsoft.bot.connector.ExecutorFactory; import com.microsoft.bot.connector.authentication.*; import com.microsoft.bot.connector.rest.RestConnectorClient; +import com.microsoft.bot.integration.ClasspathPropertiesConfiguration; +import com.microsoft.bot.integration.Configuration; +import com.microsoft.bot.integration.ConfigurationChannelProvider; import com.microsoft.bot.schema.Activity; import com.microsoft.bot.schema.ActivityTypes; import javax.servlet.*; @@ -20,8 +22,6 @@ import java.io.IOException; import java.io.InputStream; -import java.util.concurrent.CompletableFuture; -import java.util.Properties; import java.util.concurrent.CompletionException; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,59 +37,60 @@ public class EchoServlet extends HttpServlet { private ObjectMapper objectMapper; private CredentialProvider credentialProvider; private MicrosoftAppCredentials credentials; + private Configuration configuration; + private ChannelProvider channelProvider; @Override public void init() throws ServletException { - try{ - this.objectMapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .findAndRegisterModules(); + 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")); + // Load the application.properties from the classpath + configuration = new ClasspathPropertiesConfiguration(); + String appId = configuration.getProperty("MicrosoftAppId"); + String appPassword = configuration.getProperty("MicrosoftAppPassword"); - String appId = p.getProperty("MicrosoftAppId"); - String appPassword = p.getProperty("MicrosoftAppPassword"); + credentialProvider = new SimpleCredentialProvider(appId, appPassword); + channelProvider = new ConfigurationChannelProvider(configuration); - this.credentialProvider = new SimpleCredentialProvider(appId, appPassword); - this.credentials = new MicrosoftAppCredentials(appId, appPassword); - } - catch(IOException ioe){ - throw new ServletException(ioe); + if (channelProvider.isGovernment()) { + credentials = new MicrosoftGovernmentAppCredentials(appId, appPassword); + } else { + credentials = new MicrosoftAppCredentials(appId, appPassword); } } @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + protected void doPost(HttpServletRequest request, HttpServletResponse response) { try { - final Activity activity = getActivity(request); + Activity activity = getActivity(request); String authHeader = request.getHeader("Authorization"); - CompletableFuture authenticateRequest = JwtTokenValidation.authenticateRequest(activity, authHeader, credentialProvider, new SimpleChannelProvider()); - authenticateRequest.thenRunAsync(() -> { - if (activity.getType().equals(ActivityTypes.MESSAGE)) { - // reply activity with the same text - ConnectorClient connector = new RestConnectorClient(activity.getServiceUrl(), this.credentials); - connector.getConversations().sendToConversation( - activity.getConversation().getId(), - activity.createReply("Echo: " + activity.getText())); - } - }, ExecutorFactory.getExecutor()).join(); + JwtTokenValidation.authenticateRequest(activity, authHeader, credentialProvider, channelProvider) + .thenAccept(identity -> { + if (activity.getType().equals(ActivityTypes.MESSAGE)) { + // reply activity with the same text + ConnectorClient connector = new RestConnectorClient(activity.getServiceUrl(), credentials); + connector.getConversations().sendToConversation( + activity.getConversation().getId(), + activity.createReply("Echo: " + activity.getText())); + } + }) + .join(); - response.setStatus(200); + response.setStatus(HttpServletResponse.SC_ACCEPTED); } catch (CompletionException ex) { if (ex.getCause() instanceof AuthenticationException) { LOGGER.log(Level.WARNING, "Auth failed!", ex); - response.setStatus(401); - } - else { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + } else { LOGGER.log(Level.WARNING, "Execution failed", ex); - response.setStatus(500); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } catch (Exception ex) { LOGGER.log(Level.WARNING, "Execution failed", ex); - response.setStatus(500); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } diff --git a/samples/servlet-echo/src/main/resources/application.properties b/samples/servlet-echo/src/main/resources/application.properties index 660828e3e..07c01c052 100644 --- a/samples/servlet-echo/src/main/resources/application.properties +++ b/samples/servlet-echo/src/main/resources/application.properties @@ -1,2 +1,3 @@ MicrosoftAppId= -MicrosoftAppPassword= \ No newline at end of file +MicrosoftAppPassword= +#ChannelService=https://botframework.azure.us From 99d9dd31f7302d1c07c537ff3830cad87355359d Mon Sep 17 00:00:00 2001 From: Tracy Boehrer Date: Thu, 5 Sep 2019 14:44:55 -0500 Subject: [PATCH 2/3] Adjusted ARM template for Servlet sample to run on Windows. --- .../new-rg-parameters.json | 42 ------------------- .../preexisting-rg-parameters.json | 39 ----------------- .../template-with-new-rg.json | 7 ++-- .../template-with-preexisting-rg.json | 8 ++-- samples/servlet-echo/pom.xml | 4 +- 5 files changed, 8 insertions(+), 92 deletions(-) delete mode 100644 samples/servlet-echo/deploymentTemplates/new-rg-parameters.json delete mode 100644 samples/servlet-echo/deploymentTemplates/preexisting-rg-parameters.json diff --git a/samples/servlet-echo/deploymentTemplates/new-rg-parameters.json b/samples/servlet-echo/deploymentTemplates/new-rg-parameters.json deleted file mode 100644 index ead339093..000000000 --- a/samples/servlet-echo/deploymentTemplates/new-rg-parameters.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$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 deleted file mode 100644 index b6f5114fc..000000000 --- a/samples/servlet-echo/deploymentTemplates/preexisting-rg-parameters.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$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 index dcd6260a5..b12b7056f 100644 --- a/samples/servlet-echo/deploymentTemplates/template-with-new-rg.json +++ b/samples/servlet-echo/deploymentTemplates/template-with-new-rg.json @@ -116,10 +116,9 @@ "apiVersion": "2018-02-01", "location": "[variables('effectivePlanLocation')]", "sku": "[parameters('newAppServicePlanSku')]", - "kind": "linux", + "kind": "app", "properties": { - "name": "[variables('appServicePlanName')]", - "reserved":true + "name": "[variables('appServicePlanName')]" } }, { @@ -188,4 +187,4 @@ } } ] -} \ 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 index b790d2bdc..5f5b6fba9 100644 --- a/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg.json +++ b/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg.json @@ -87,10 +87,9 @@ "apiVersion": "2018-02-01", "location": "[variables('resourcesLocation')]", "sku": "[parameters('newAppServicePlanSku')]", - "kind": "linux", + "kind": "app", "properties": { - "name": "[variables('servicePlanName')]", - "reserved":true + "name": "[variables('servicePlanName')]" } }, { @@ -107,7 +106,6 @@ "name": "[variables('webAppName')]", "serverFarmId": "[variables('servicePlanName')]", "siteConfig": { - "linuxFxVersion": "JAVA|8-jre8", "appSettings": [ { "name": "JAVA_OPTS", @@ -155,4 +153,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/samples/servlet-echo/pom.xml b/samples/servlet-echo/pom.xml index 36f020ab7..8a01391e8 100644 --- a/samples/servlet-echo/pom.xml +++ b/samples/servlet-echo/pom.xml @@ -137,8 +137,8 @@ - linux - jre8 + windows + 1.8 tomcat 9.0 From d749396e16260105e0f5e998add2a77d73d20d58 Mon Sep 17 00:00:00 2001 From: Tracy Boehrer Date: Thu, 5 Sep 2019 17:44:58 -0500 Subject: [PATCH 3/3] Deployment changes to support Gov Azure. --- .../template-with-new-rg-gov.json | 192 ++++++++++++++++++ .../template-with-preexisting-rg-gov.json | 158 ++++++++++++++ samples/servlet-echo/pom.xml | 25 ++- .../bot/sample/servlet/EchoServlet.java | 28 ++- .../src/main/resources/log4j2.json | 18 ++ 5 files changed, 408 insertions(+), 13 deletions(-) create mode 100644 samples/servlet-echo/deploymentTemplates/template-with-new-rg-gov.json create mode 100644 samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg-gov.json create mode 100644 samples/servlet-echo/src/main/resources/log4j2.json diff --git a/samples/servlet-echo/deploymentTemplates/template-with-new-rg-gov.json b/samples/servlet-echo/deploymentTemplates/template-with-new-rg-gov.json new file mode 100644 index 000000000..d5264be99 --- /dev/null +++ b/samples/servlet-echo/deploymentTemplates/template-with-new-rg-gov.json @@ -0,0 +1,192 @@ +{ + "$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": "S1", + "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": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "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.us')]", + "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": "app", + "properties": { + "name": "[variables('appServicePlanName')]" + } + }, + { + "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.azureportal.usgovcloudapi.net", + "https://botservice-ms.hosting.azureportal.usgovcloudapi.net", + "https://hosting.onecloud.azure-test.net/" + ], + "supportCredentials": false + } + } + } + }, + { + "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": {} + } + } + } + ] +} diff --git a/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg-gov.json b/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg-gov.json new file mode 100644 index 000000000..c91921677 --- /dev/null +++ b/samples/servlet-echo/deploymentTemplates/template-with-preexisting-rg-gov.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": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "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.us')]", + "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": "app", + "properties": { + "name": "[variables('servicePlanName')]" + } + }, + { + "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": { + "appSettings": [ + { + "name": "JAVA_OPTS", + "value": "-Dserver.port=80" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.azureportal.usgovcloudapi.net", + "https://botservice-ms.hosting.azureportal.usgovcloudapi.net", + "https://hosting.onecloud.azure-test.net/" + ], + "supportCredentials": false + } + } + } + }, + { + "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'))]" + ] + } + ] +} diff --git a/samples/servlet-echo/pom.xml b/samples/servlet-echo/pom.xml index 8a01391e8..c35238821 100644 --- a/samples/servlet-echo/pom.xml +++ b/samples/servlet-echo/pom.xml @@ -61,16 +61,29 @@ jackson-datatype-jsr310 2.9.8 + + + org.slf4j + slf4j-api + 1.7.22 + - org.slf4j - slf4j-api - 1.7.26 + org.apache.logging.log4j + log4j-api + 2.11.0 - org.slf4j - slf4j-simple - 1.7.26 + org.apache.logging.log4j + log4j-core + 2.11.0 + + org.slf4j + slf4j-log4j12 + 1.7.25 + test + + com.microsoft.bot bot-schema 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 index 2c8d55874..49f13a9d3 100644 --- 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 @@ -16,15 +16,17 @@ import com.microsoft.bot.integration.ConfigurationChannelProvider; import com.microsoft.bot.schema.Activity; import com.microsoft.bot.schema.ActivityTypes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; import java.io.InputStream; +import java.io.PrintWriter; import java.util.concurrent.CompletionException; -import java.util.logging.Level; -import java.util.logging.Logger; /** * This is the Servlet that will receive incoming Channel Activity messages. @@ -32,7 +34,7 @@ @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 static final Logger LOGGER = LoggerFactory.getLogger(EchoServlet.class); private ObjectMapper objectMapper; private CredentialProvider credentialProvider; @@ -61,9 +63,21 @@ public void init() throws ServletException { } } + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + try (PrintWriter out = response.getWriter()) { + out.println("hello world"); + response.setStatus(HttpServletResponse.SC_ACCEPTED); + } catch (Throwable t) { + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { try { + LOGGER.debug("Received request"); + Activity activity = getActivity(request); String authHeader = request.getHeader("Authorization"); @@ -82,14 +96,14 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) response.setStatus(HttpServletResponse.SC_ACCEPTED); } catch (CompletionException ex) { if (ex.getCause() instanceof AuthenticationException) { - LOGGER.log(Level.WARNING, "Auth failed!", ex); + LOGGER.error("Auth failed!", ex); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } else { - LOGGER.log(Level.WARNING, "Execution failed", ex); + LOGGER.error("Execution failed", ex); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } catch (Exception ex) { - LOGGER.log(Level.WARNING, "Execution failed", ex); + LOGGER.error("Execution failed", ex); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } @@ -97,7 +111,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) // 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); + LOGGER.debug(body); return objectMapper.readValue(body, Activity.class); } diff --git a/samples/servlet-echo/src/main/resources/log4j2.json b/samples/servlet-echo/src/main/resources/log4j2.json new file mode 100644 index 000000000..67c0ad530 --- /dev/null +++ b/samples/servlet-echo/src/main/resources/log4j2.json @@ -0,0 +1,18 @@ +{ + "configuration": { + "name": "Default", + "appenders": { + "Console": { + "name": "Console-Appender", + "target": "SYSTEM_OUT", + "PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"} + } + }, + "loggers": { + "root": { + "level": "debug", + "appender-ref": {"ref": "Console-Appender","level": "debug"} + } + } + } +}