diff --git a/libraries/bot-integration-spring6/pom.xml b/libraries/bot-integration-spring6/pom.xml new file mode 100644 index 000000000..70e846c02 --- /dev/null +++ b/libraries/bot-integration-spring6/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + + + com.microsoft.bot + bot-java + 4.15.0-SNAPSHOT + ../../pom.xml + + + bot-integration-spring6 + jar + + ${project.groupId}:${project.artifactId} + Bot Framework Integration Spring 6.x + https://dev.botframework.com/ + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + + + + + + Bot Framework Development + + Microsoft + https://dev.botframework.com/ + + + + + scm:git:https://github.com/Microsoft/botbuilder-java + scm:git:https://github.com/Microsoft/botbuilder-java + https://github.com/Microsoft/botbuilder-java + + + + UTF-8 + false + + + + + + org.springframework + spring-framework-bom + 6.0.13 + pom + import + + + + + + + org.springframework + spring-web + + + org.springframework + spring-context + + + com.microsoft.bot + bot-integration-core + + + + + + build + + true + + + + + + diff --git a/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/BotController.java b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/BotController.java new file mode 100644 index 000000000..57a49ae1d --- /dev/null +++ b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/BotController.java @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.bot.integration.spring; + +import com.microsoft.bot.builder.Bot; +import com.microsoft.bot.connector.authentication.AuthenticationException; +import com.microsoft.bot.integration.BotFrameworkHttpAdapter; +import com.microsoft.bot.schema.Activity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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 java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +/** + * This is the default controller that will receive incoming Channel Activity + * messages. + * + *

+ * This controller is suitable in most cases. Bots that want to use this + * controller should do so by using the @Import({BotController.class}) + * annotation. See any of the samples Application class for an example. + *

+ */ +@RestController +public class BotController { + /** + * The slf4j Logger to use. Note that slf4j is configured by providing Log4j + * dependencies in the POM, and corresponding Log4j configuration in the + * 'resources' folder. + */ + private Logger logger = LoggerFactory.getLogger(BotController.class); + + /** + * The BotFrameworkHttpAdapter to use. Note it is provided by dependency + * injection via the constructor. + */ + private final BotFrameworkHttpAdapter adapter; + + /** + * The Bot to use. Note it is provided by dependency + * injection via the constructor. + */ + private final Bot bot; + + /** + * Spring will use this constructor for creation. + * + *

+ * The Bot application should define class that implements {@link Bot} and + * annotate it with @Component. + *

+ * + * @see BotDependencyConfiguration + * + * @param withAdapter The BotFrameworkHttpAdapter to use. + * @param withBot The Bot to use. + */ + public BotController(BotFrameworkHttpAdapter withAdapter, Bot withBot) { + adapter = withAdapter; + bot = withBot; + } + + /** + * This will receive incoming Channel Activities. + * + * @param activity The incoming Activity. + * @param authHeader The incoming Authorization header. + * @return The request response. + */ + @PostMapping("/api/messages") + public CompletableFuture> incoming( + @RequestBody Activity activity, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + + return adapter.processIncomingActivity(authHeader, activity, bot) + + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity<>( + result.getBody(), + HttpStatus.valueOf(result.getStatus()) + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } +} diff --git a/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/BotDependencyConfiguration.java b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/BotDependencyConfiguration.java new file mode 100644 index 000000000..025a7de73 --- /dev/null +++ b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/BotDependencyConfiguration.java @@ -0,0 +1,175 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.bot.integration.spring; + +import com.microsoft.bot.builder.ConversationState; +import com.microsoft.bot.builder.MemoryStorage; +import com.microsoft.bot.builder.Storage; +import com.microsoft.bot.builder.UserState; +import com.microsoft.bot.builder.inspection.InspectionState; +import com.microsoft.bot.connector.ExecutorFactory; +import com.microsoft.bot.connector.authentication.AuthenticationConfiguration; +import com.microsoft.bot.connector.authentication.ChannelProvider; +import com.microsoft.bot.connector.authentication.CredentialProvider; +import com.microsoft.bot.integration.BotFrameworkHttpAdapter; +import com.microsoft.bot.integration.ClasspathPropertiesConfiguration; +import com.microsoft.bot.integration.Configuration; +import com.microsoft.bot.integration.ConfigurationChannelProvider; +import com.microsoft.bot.integration.ConfigurationCredentialProvider; +import org.springframework.context.annotation.Bean; + +import java.util.concurrent.ExecutorService; + +/** + * This provides the default dependency creation for a Bot application. + * + *

+ * This class should be subclassed by a class with the + * {@link org.springframework.context.annotation.Configuration} annotation (or + * SpringBootApplication annotation). + *

+ * + *

+ * The Bot should be annotated with @Component, possibly including @AutoWired to + * indicate which constructor to use. + *

+ */ +public abstract class BotDependencyConfiguration { + /** + * Returns an ExecutorService. + * + *

+ * For now, return the bot-connector ExecutorService. This is an area of + * consideration. The goal here is to have a common ExecutorService to avoid + * multiple thread pools. + *

+ * + * @return An ExecutorService. + */ + @Bean + public ExecutorService getExecutorService() { + return ExecutorFactory.getExecutor(); + } + + /** + * Returns the Configuration for the application. + * + * By default, it uses the {@link ClasspathPropertiesConfiguration} class. + * Default scope of Singleton. + * + * @return A Configuration object. + */ + @Bean + public Configuration getConfiguration() { + return new ClasspathPropertiesConfiguration(); + } + + + /** + * Returns the AuthenticationConfiguration for the application. + * + * By default, it uses the {@link AuthenticationConfiguration} class. + * Default scope of Singleton. + * @param configuration The Configuration object to read from. + * @return An AuthenticationConfiguration object. + */ + @Bean + public AuthenticationConfiguration getAuthenticationConfiguration(Configuration configuration) { + return new AuthenticationConfiguration(); + } + + /** + * Returns the CredentialProvider for the application. + * + * By default, it uses the {@link ConfigurationCredentialProvider} class. + * Default scope of Singleton. + * + * @param configuration The Configuration object to read from. + * @return A CredentialProvider object. + * + * @see #getConfiguration() + */ + @Bean + public CredentialProvider getCredentialProvider(Configuration configuration) { + return new ConfigurationCredentialProvider(configuration); + } + + /** + * Returns the ChannelProvider for the application. + * + * By default, it uses the {@link ConfigurationChannelProvider} class. Default + * scope of Singleton. + * + * @param configuration The Configuration object to read from. + * @return A ChannelProvider object. + * + * @see #getConfiguration() + */ + @Bean + public ChannelProvider getChannelProvider(Configuration configuration) { + return new ConfigurationChannelProvider(configuration); + } + + /** + * Returns the BotFrameworkHttpAdapter for the application. + * + * By default, it uses the {@link BotFrameworkHttpAdapter} class. Default scope + * of Singleton. + * + * @param configuration The Configuration object to read from. + * @return A BotFrameworkHttpAdapter object. + * + * @see #getConfiguration() + */ + @Bean + public BotFrameworkHttpAdapter getBotFrameworkHttpAdaptor(Configuration configuration) { + return new BotFrameworkHttpAdapter(configuration); + } + + /** + * Returns a {@link Storage} object. Default scope of Singleton. + * + * @return A Storage object. + */ + @Bean + public Storage getStorage() { + return new MemoryStorage(); + } + + /** + * Returns a ConversationState object. Default scope of Singleton. + * + * @param storage The Storage object to use. + * @return A ConversationState object. + */ + @Bean + public ConversationState getConversationState(Storage storage) { + return new ConversationState(storage); + } + + /** + * Returns a UserState object. Default scope of Singleton. + * + * @param storage The Storage object to use. + * @return A UserState object. + */ + @Bean + public UserState getUserState(Storage storage) { + return new UserState(storage); + } + + /** + * Creates an InspectionState used by + * {@link com.microsoft.bot.builder.inspection.InspectionMiddleware}. Default + * scope of Singleton. + * + * @param storage The Storage to use. + * {@link BotDependencyConfiguration#getStorage()} + * @return An InspectionState object that uses the specified storage. + */ + @Bean + public InspectionState getInspectionState(Storage storage) { + return new InspectionState(storage); + } +} diff --git a/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/ChannelServiceController.java b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/ChannelServiceController.java new file mode 100644 index 000000000..4ee1fdb1c --- /dev/null +++ b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/ChannelServiceController.java @@ -0,0 +1,546 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MT License. + +package com.microsoft.bot.integration.spring; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import com.microsoft.bot.builder.ChannelServiceHandler; +import com.microsoft.bot.connector.authentication.AuthenticationException; +import com.microsoft.bot.schema.Activity; +import com.microsoft.bot.schema.AttachmentData; +import com.microsoft.bot.schema.ChannelAccount; +import com.microsoft.bot.schema.ConversationParameters; +import com.microsoft.bot.schema.ConversationResourceResponse; +import com.microsoft.bot.schema.ConversationsResult; +import com.microsoft.bot.schema.PagedMembersResult; +import com.microsoft.bot.schema.ResourceResponse; +import com.microsoft.bot.schema.Transcript; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * A super.class for a skill controller. + */ +// Note: this class instanceof marked as abstract to prevent the ASP runtime from registering it as a controller. +public abstract class ChannelServiceController { + + /** + * The slf4j Logger to use. Note that slf4j is configured by providing Log4j + * dependencies in the POM, and corresponding Log4j configuration in the + * 'resources' folder. + */ + private Logger logger = LoggerFactory.getLogger(BotController.class); + + private final ChannelServiceHandler handler; + + /** + * Initializes a new instance of the {@link ChannelServiceController} + * class. + * + * @param handler A {@link ChannelServiceHandler} that will handle + * the incoming request. + */ + protected ChannelServiceController(ChannelServiceHandler handler) { + this.handler = handler; + } + + /** + * SendToConversation. + * + * @param conversationId Conversation Id. + * @param activity Activity to send. + * @param authHeader Authentication header. + * + * @return A ResourceResponse. + */ + @PostMapping("v3/conversations/{conversationId}/activities") + public CompletableFuture> sendToConversation( + @PathVariable String conversationId, + @RequestBody Activity activity, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + + return handler.handleSendToConversation(authHeader, conversationId, activity) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * ReplyToActivity. + * + * @param conversationId Conversation Id. + * @param activityId activityId the reply is to (OPTONAL). + * @param activity Activity to send. + * @param authHeader Authentication header. + * + * @return A ResourceResponse. + */ + @PostMapping("v3/conversations/{conversationId}/activities/{activityId}") + public CompletableFuture> replyToActivity( + @PathVariable String conversationId, + @PathVariable String activityId, + @RequestBody Activity activity, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleReplyToActivity(authHeader, conversationId, activityId, activity) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * UpdateActivity. + * + * @param conversationId Conversation Id. + * @param activityId activityId to update. + * @param activity replacement Activity. + * @param authHeader Authentication header. + * + * @return A ResourceResponse. + */ + @PutMapping("v3/conversations/{conversationId}/activities/{activityId}") + public CompletableFuture> updateActivity( + @PathVariable String conversationId, + @PathVariable String activityId, + @RequestBody Activity activity, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleUpdateActivity(authHeader, conversationId, activityId, activity) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * DeleteActivity. + * + * @param conversationId Conversation Id. + * @param activityId activityId to delete. + * @param authHeader Authentication header. + * + * @return A void result if successful. + */ + @DeleteMapping("v3/conversations/{conversationId}/activities/{activityId}") + public CompletableFuture> deleteActivity( + @PathVariable String conversationId, + @PathVariable String activityId, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleDeleteActivity(authHeader, conversationId, activityId) + .handle((result, exception) -> { + if (exception == null) { + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * GetActivityMembers. + * + * Markdown=Content\Methods\GetActivityMembers.getmd(). + * + * @param conversationId Conversation Id. + * @param activityId Activity Id. + * @param authHeader Authentication header. + * + * @return A list of ChannelAccount. + */ + @GetMapping("v3/conversations/{conversationId}/activities/{activityId}/members") + public CompletableFuture>> getActivityMembers( + @PathVariable String conversationId, + @PathVariable String activityId, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleGetActivityMembers(authHeader, conversationId, activityId) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity>( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * CreateConversation. + * + * @param parameters Parameters to create the conversation from. + * @param authHeader Authentication header. + * + * @return A ConversationResourceResponse. + */ + @PostMapping("v3/conversations") + public CompletableFuture> createConversation( + @RequestBody ConversationParameters parameters, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleCreateConversation(authHeader, parameters) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * GetConversations. + * + * @param conversationId the conversation id to get conversations for. + * @param continuationToken skip or continuation token. + * @param authHeader Authentication header. + * + * @return A ConversationsResult. + */ + @GetMapping("v3/conversations") + public CompletableFuture> getConversations( + @RequestParam String conversationId, + @RequestParam String continuationToken, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleGetConversations(authHeader, conversationId, continuationToken) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * GetConversationMembers. + * + * @param conversationId Conversation Id. + * @param authHeader Authentication header. + * + * @return A List of ChannelAccount. + */ + @GetMapping("v3/conversations/{conversationId}/members") + public CompletableFuture>> getConversationMembers( + @PathVariable String conversationId, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleGetConversationMembers(authHeader, conversationId) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity>( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * GetConversationPagedMembers. + * + * @param conversationId Conversation Id. + * @param pageSize Suggested page size. + * @param continuationToken Continuation Token. + * @param authHeader Authentication header. + * + * @return A PagedMembersResult. + */ + @GetMapping("v3/conversations/{conversationId}/pagedmembers") + public CompletableFuture> getConversationPagedMembers( + @PathVariable String conversationId, + @RequestParam(name = "pageSize", defaultValue = "-1") int pageSize, + @RequestParam(name = "continuationToken") String continuationToken, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleGetConversationPagedMembers(authHeader, conversationId, pageSize, continuationToken) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * DeleteConversationMember. + * + * @param conversationId Conversation Id. + * @param memberId D of the member to delete from this + * conversation. + * @param authHeader Authentication header. + * + * @return A void result. + */ + @DeleteMapping("v3/conversations/{conversationId}/members/{memberId}") + public CompletableFuture> deleteConversationMember( + @PathVariable String conversationId, + @PathVariable String memberId, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleDeleteConversationMember(authHeader, conversationId, memberId) + .handle((result, exception) -> { + if (exception == null) { + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * SendConversationHistory. + * + * @param conversationId Conversation Id. + * @param history Historic activities. + * @param authHeader Authentication header. + * + * @return A ResourceResponse. + */ + @PostMapping("v3/conversations/{conversationId}/activities/history") + public CompletableFuture> sendConversationHistory( + @PathVariable String conversationId, + @RequestBody Transcript history, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleSendConversationHistory(authHeader, conversationId, history) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } + + /** + * UploadAttachment. + * + * @param conversationId Conversation Id. + * @param attachmentUpload Attachment data. + * @param authHeader Authentication header. + * + * @return A ResourceResponse. + */ + @PostMapping("v3/conversations/{conversationId}/attachments") + public CompletableFuture> uploadAttachment( + @PathVariable String conversationId, + @RequestBody AttachmentData attachmentUpload, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader + ) { + return handler.handleUploadAttachment(authHeader, conversationId, attachmentUpload) + .handle((result, exception) -> { + if (exception == null) { + if (result != null) { + return new ResponseEntity( + result, + HttpStatus.OK + ); + } + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + + logger.error("Exception handling message", exception); + + if (exception instanceof CompletionException) { + if (exception.getCause() instanceof AuthenticationException) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } else { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + }); + } +} diff --git a/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/package-info.java b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/package-info.java new file mode 100644 index 000000000..b40602d73 --- /dev/null +++ b/libraries/bot-integration-spring6/src/main/java/com/microsoft/bot/integration/spring/package-info.java @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. + +/** + * This package contains the classes for com.microsoft.bot.integration.spring. + */ +@Deprecated +package com.microsoft.bot.integration.spring; diff --git a/pom.xml b/pom.xml index 95c92d755..7e67d14d0 100644 --- a/pom.xml +++ b/pom.xml @@ -468,6 +468,7 @@ libraries/bot-applicationinsights libraries/bot-azure libraries/bot-integration-spring + libraries/bot-integration-spring6