Merge branch 'master' into tb-botbuilder

This commit is contained in:
Tracy Boehrer 2019-09-06 20:20:16 -05:00
Родитель c67a4acf09 a168d7be55
Коммит abcecf7ad7
11 изменённых файлов: 463 добавлений и 144 удалений

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

@ -3,6 +3,7 @@ package com.microsoft.bot.integration;
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);
}

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

@ -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": ""
}
}
}

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

@ -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": ""
}
}
}

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

@ -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": {}
}
}
}
]
}

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

@ -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 @@
}
}
]
}
}

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

@ -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'))]"
]
}
]
}

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

@ -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 @@
]
}
]
}
}

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

@ -61,16 +61,29 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.26</version>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.microsoft.bot</groupId>
<artifactId>bot-schema</artifactId>
@ -81,6 +94,11 @@
<artifactId>bot-connector</artifactId>
<version>4.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.microsoft.bot</groupId>
<artifactId>bot-integration-core</artifactId>
<version>4.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<repositories>
@ -132,8 +150,8 @@
</property>
</appSettings>
<runtime>
<os>linux</os>
<javaVersion>jre8</javaVersion>
<os>windows</os>
<javaVersion>1.8</javaVersion>
<webContainer>tomcat 9.0</webContainer>
</runtime>
<deployment>

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

@ -9,22 +9,24 @@ import com.fasterxml.jackson.databind.JsonMappingException;
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 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.util.concurrent.CompletableFuture;
import java.util.Properties;
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,71 +34,84 @@ import java.util.logging.Logger;
@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;
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 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 {
final Activity activity = getActivity(request);
LOGGER.debug("Received request");
Activity activity = getActivity(request);
String authHeader = request.getHeader("Authorization");
CompletableFuture<ClaimsIdentity> 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 {
LOGGER.log(Level.WARNING, "Execution failed", ex);
response.setStatus(500);
LOGGER.error("Auth failed!", ex);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
LOGGER.error("Execution failed", ex);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
} catch (Exception ex) {
LOGGER.log(Level.WARNING, "Execution failed", ex);
response.setStatus(500);
LOGGER.error("Execution failed", ex);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
// 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);
}

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

@ -1,2 +1,3 @@
MicrosoftAppId=
MicrosoftAppPassword=
MicrosoftAppPassword=
#ChannelService=https://botframework.azure.us

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

@ -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"}
}
}
}
}