From 2aaa43a2fe2a2badd22a66ca19a22c3b143353f6 Mon Sep 17 00:00:00 2001 From: Tracy Boehrer Date: Tue, 3 Sep 2019 15:35:02 -0500 Subject: [PATCH] Removed use of Observables from bot-connector and added more tests. --- .../bot/builder/BotFrameworkAdapter.java | 9 +- .../microsoft/bot/connector/AsyncHelper.java | 48 -- .../microsoft/bot/connector/Attachments.java | 56 +- .../bot/connector/Conversations.java | 492 +--------------- .../bot/connector/rest/RestAttachments.java | 97 +--- .../bot/connector/rest/RestConversations.java | 544 ++++-------------- .../bot/connector/ConversationsTest.java | 340 +++++++++-- .../CreateConversationWithNullParameter.json | 24 + .../DeleteActivityWithNullActivityId.json | 48 ++ .../DeleteActivityWithNullConversationId.json | 48 ++ .../GetActivityMembersWithNullActivityId.json | 25 + ...ActivityMembersWithNullConversationId.json | 25 + ...ersationMembersWithNullConversationId.json | 25 + ...PagedMembersWithInvalidConversationId.json | 43 ++ .../ReplyToActivityWithNullActivity.json | 49 ++ .../ReplyToActivityWithNullActivityId.json | 49 ++ ...ReplyToActivityWithNullConversationId.json | 49 ++ .../ReplyToActivityWithNullReply.json | 70 +++ .../SendToConversationWithNullActivity.json | 48 ++ ...dToConversationWithNullConversationId.json | 48 ++ .../UpdateActivityWithNullActivity.json | 70 +++ .../UpdateActivityWithNullActivityId.json | 70 +++ .../UpdateActivityWithNullConversationId.json | 70 +++ .../bot/sample/spring/BotController.java | 59 +- 24 files changed, 1250 insertions(+), 1156 deletions(-) delete mode 100644 libraries/bot-connector/src/main/java/com/microsoft/bot/connector/AsyncHelper.java create mode 100644 libraries/bot-connector/src/test/resources/session-records/CreateConversationWithNullParameter.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullActivityId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullConversationId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullActivityId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullConversationId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/GetConversationMembersWithNullConversationId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/GetConversationPagedMembersWithInvalidConversationId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivity.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivityId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullConversationId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullReply.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullActivity.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullConversationId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivity.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivityId.json create mode 100644 libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullConversationId.json diff --git a/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/BotFrameworkAdapter.java b/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/BotFrameworkAdapter.java index cad5b5525..c2e1143eb 100644 --- a/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/BotFrameworkAdapter.java +++ b/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/BotFrameworkAdapter.java @@ -3,7 +3,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import com.microsoft.bot.connector.AsyncHelper; import com.microsoft.bot.connector.ConnectorClient; import com.microsoft.bot.connector.Conversations; import com.microsoft.bot.connector.ExecutorFactory; @@ -351,9 +350,8 @@ public ResourceResponse UpdateActivity(TurnContext context, Activity activity) { public void DeleteActivity(TurnContext context, ConversationReference reference) { RestConnectorClient connectorClient = context.getServices().Get("ConnectorClient"); try { - AsyncHelper.completableSingleFutureFromObservable( - connectorClient.getConversations().deleteConversationMemberAsync( - reference.getConversation().getId(), reference.getActivityId())).join(); + connectorClient.getConversations().deleteConversationMemberAsync( + reference.getConversation().getId(), reference.getActivityId()).join(); } catch (CompletionException e) { e.printStackTrace(); throw new RuntimeException(String.format("Failed deleting activity (%s)", e.toString())); @@ -588,8 +586,7 @@ public CompletableFuture CreateConversation(String channelId, String serviceUrl, } Conversations conversations = connectorClient.getConversations(); - CompletableFuture result = AsyncHelper.completableSingleFutureFromObservable( - conversations.createConversationAsync(conversationParameters)); + CompletableFuture result = conversations.createConversationAsync(conversationParameters); ConversationResourceResponse response = result.join(); diff --git a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/AsyncHelper.java b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/AsyncHelper.java deleted file mode 100644 index 5eb56e3de..000000000 --- a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/AsyncHelper.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.microsoft.bot.connector; - -import rx.Observable; - -import java.util.List; -import java.util.concurrent.CompletableFuture; - -public class AsyncHelper { - private AsyncHelper() { - } - - /** - * Creates a CompletableFuture from an RxJava Observable. - * - * Because Observables are n+, this results in a List return values. - * - * @param observable The Observable to convert. - * @param The return type of the Observable. - * @return A CompletableFuture of List. - */ - public static CompletableFuture> completableFutureFromObservable(Observable observable) { - final CompletableFuture> future = new CompletableFuture<>(); - observable - .doOnError(future::completeExceptionally) - .toList() - .forEach(future::complete); - return future; - } - - /** - * Creates a CompletableFuture from an Rx Java Observable, enforcing a single - * result of type T. - * - * @param observable The Observable to convert. - * @param The returns type. - * @return A CompletableFutre of type T. - */ - public static CompletableFuture completableSingleFutureFromObservable(Observable observable) { - final CompletableFuture future = new CompletableFuture<>(); - observable - .doOnError(future::completeExceptionally) - .single(); - return future; - } -} diff --git a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Attachments.java b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Attachments.java index d0bdf3c78..8c105c458 100644 --- a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Attachments.java +++ b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Attachments.java @@ -7,12 +7,9 @@ package com.microsoft.bot.connector; import com.microsoft.bot.schema.AttachmentInfo; -import com.microsoft.rest.ServiceCallback; -import com.microsoft.rest.ServiceFuture; -import com.microsoft.rest.ServiceResponse; -import rx.Observable; import java.io.InputStream; +import java.util.concurrent.CompletableFuture; /** * An instance of this class provides access to all the operations defined @@ -30,18 +27,6 @@ public interface Attachments { */ AttachmentInfo getAttachmentInfo(String attachmentId); - /** - * GetAttachmentInfo. - * Get AttachmentInfo structure describing the attachment views. - * - * @param attachmentId attachment id - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @return the {@link ServiceFuture} object - * @throws IllegalArgumentException thrown if parameters fail the validation - */ - ServiceFuture getAttachmentInfoAsync(String attachmentId, - final ServiceCallback serviceCallback); - /** * GetAttachmentInfo. * Get AttachmentInfo structure describing the attachment views. @@ -50,17 +35,7 @@ ServiceFuture getAttachmentInfoAsync(String attachmentId, * @return the observable to the AttachmentInfo object * @throws IllegalArgumentException thrown if parameters fail the validation */ - Observable getAttachmentInfoAsync(String attachmentId); - - /** - * GetAttachmentInfo. - * Get AttachmentInfo structure describing the attachment views. - * - * @param attachmentId attachment id - * @return the observable to the AttachmentInfo object - * @throws IllegalArgumentException thrown if parameters fail the validation - */ - Observable> getAttachmentInfoWithServiceResponseAsync(String attachmentId); + CompletableFuture getAttachmentInfoAsync(String attachmentId); /** * GetAttachment. @@ -74,19 +49,6 @@ ServiceFuture getAttachmentInfoAsync(String attachmentId, */ InputStream getAttachment(String attachmentId, String viewId); - /** - * GetAttachment. - * Get the named view as binary content. - * - * @param attachmentId attachment id - * @param viewId View id from attachmentInfo - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @return the {@link ServiceFuture} object - * @throws IllegalArgumentException thrown if parameters fail the validation - */ - ServiceFuture getAttachmentAsync(String attachmentId, String viewId, - final ServiceCallback serviceCallback); - /** * GetAttachment. * Get the named view as binary content. @@ -96,17 +58,5 @@ ServiceFuture getAttachmentAsync(String attachmentId, String viewId * @return the observable to the InputStream object * @throws IllegalArgumentException thrown if parameters fail the validation */ - Observable getAttachmentAsync(String attachmentId, String viewId); - - /** - * GetAttachment. - * Get the named view as binary content. - * - * @param attachmentId attachment id - * @param viewId View id from attachmentInfo - * @return the observable to the InputStream object - * @throws IllegalArgumentException thrown if parameters fail the validation - */ - Observable> getAttachmentWithServiceResponseAsync(String attachmentId, String viewId); - + CompletableFuture getAttachmentAsync(String attachmentId, String viewId); } diff --git a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Conversations.java b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Conversations.java index 53f043e51..7c3afbdcd 100644 --- a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Conversations.java +++ b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/Conversations.java @@ -11,12 +11,10 @@ package com.microsoft.bot.connector; import com.microsoft.bot.schema.*; -import com.microsoft.rest.ServiceCallback; -import com.microsoft.rest.ServiceFuture; import com.microsoft.rest.ServiceResponse; -import rx.Observable; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * An instance of this class provides access to all the operations defined @@ -40,23 +38,6 @@ public interface Conversations { */ ConversationsResult getConversations(); - /** - * GetConversations. - * List the Conversations in which this bot has participated. - * GET from this method with a skip token - * The return value is a ConversationsResult, which contains an array of ConversationMembers and a skip token. - * If the skip token is not empty, then there are further values to be returned. Call this method again with - * the returned token to get more values. - * - * Each ConversationMembers object contains the ID of the conversation and an array of ChannelAccounts that - * describe the members of the conversation. - * - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture getConversationsAsync(ServiceCallback serviceCallback); - /** * GetConversations. * List the Conversations in which this bot has participated. @@ -71,23 +52,7 @@ public interface Conversations { * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the ConversationsResult object */ - Observable getConversationsAsync(); - - /** - * GetConversations. - * List the Conversations in which this bot has participated. - * GET from this method with a skip token - * The return value is a ConversationsResult, which contains an array of ConversationMembers and a skip token. - * If the skip token is not empty, then there are further values to be returned. Call this method again with the - * returned token to get more values. - * - * Each ConversationMembers object contains the ID of the conversation and an array of ChannelAccounts that - * describe the members of the conversation. - * - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the ConversationsResult object - */ - Observable> getConversationsWithServiceResponseAsync(); + CompletableFuture getConversationsAsync(); /** * GetConversations. @@ -107,40 +72,6 @@ public interface Conversations { */ ConversationsResult getConversations(String continuationToken); - /** - * GetConversations. - * List the Conversations in which this bot has participated. - * GET from this method with a skip token - * The return value is a ConversationsResult, which contains an array of ConversationMembers and a skip token. - * If the skip token is not empty, then there are further values to be returned. Call this method again with the - * returned token to get more values. - * Each ConversationMembers object contains the ID of the conversation and an array of ChannelAccounts that - * describe the members of the conversation. - * - * @param continuationToken skip or continuation token - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture getConversationsAsync( - String continuationToken, ServiceCallback serviceCallback); - - /** - * GetConversations. - * List the Conversations in which this bot has participated. - * GET from this method with a skip token - * The return value is a ConversationsResult, which contains an array of ConversationMembers and a skip token. - * If the skip token is not empty, then there are further values to be returned. Call this method again with the - * returned token to get more values. - * Each ConversationMembers object contains the ID of the conversation and an array of ChannelAccounts that - * describe the members of the conversation. - * - * @param continuationToken skip or continuation token - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the ConversationsResult object - */ - Observable getConversationsAsync(String continuationToken); - /** * GetConversations. * List the Conversations in which this bot has participated. @@ -155,7 +86,7 @@ ServiceFuture getConversationsAsync( * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the ConversationsResult object */ - Observable> getConversationsWithServiceResponseAsync(String continuationToken); + CompletableFuture getConversationsAsync(String continuationToken); /** * CreateConversation. @@ -181,31 +112,6 @@ ServiceFuture getConversationsAsync( */ ConversationResourceResponse createConversation(ConversationParameters parameters); - /** - * CreateConversation. - * Create a new Conversation. - * POST to this method with a - * Bot being the bot creating the conversation - * IsGroup set to true if this is not a direct message (default is false) - * Members array contining the members you want to have be in the conversation. - * The return value is a ResourceResponse which contains a conversation id which is suitable for use in the - * message payload and REST API uris. - * Most channels only support the semantics of bots initiating a direct message conversation. An example of how - * to do that would be: - * ``` - * var resource = await connector.conversations.CreateConversation(new ConversationParameters(){ Bot = bot, - * members = new ChannelAccount[] { new ChannelAccount("user1") } ); - * await connect.Conversations.SendToConversationAsync(resource.Id, new Activity() ... ) ; - * ``` - * - * @param parameters Parameters to create the conversation from - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture createConversationAsync( - ConversationParameters parameters, ServiceCallback serviceCallback); - /** * CreateConversation. * Create a new Conversation. @@ -227,31 +133,7 @@ ServiceFuture createConversationAsync( * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the ConversationResourceResponse object */ - Observable createConversationAsync(ConversationParameters parameters); - - /** - * CreateConversation. - * Create a new Conversation. - * POST to this method with a - * Bot being the bot creating the conversation - * IsGroup set to true if this is not a direct message (default is false) - * Members array contining the members you want to have be in the conversation. - * The return value is a ResourceResponse which contains a conversation id which is suitable for use - * in the message payload and REST API uris. - * Most channels only support the semantics of bots initiating a direct message conversation. An example of how - * to do that would be: - * ``` - * var resource = await connector.conversations.CreateConversation(new ConversationParameters(){ Bot = bot, - * members = new ChannelAccount[] { new ChannelAccount("user1") } ); - * await connect.Conversations.SendToConversationAsync(resource.Id, new Activity() ... ) ; - * ```. - * - * @param parameters Parameters to create the conversation from - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the ConversationResourceResponse object - */ - Observable> createConversationWithServiceResponseAsync( - ConversationParameters parameters); + CompletableFuture createConversationAsync(ConversationParameters parameters); /** * SendToConversation. @@ -272,26 +154,6 @@ Observable> createConversationWith */ ResourceResponse sendToConversation(String conversationId, Activity activity); - /** - * SendToConversation. - * This method allows you to send an activity to the end of a conversation. - * This is slightly different from ReplyToActivity(). - * SendToConverstion(conversationId) - will append the activity to the end of the conversation according to the - * timestamp or semantics of the channel. - * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply to another activity, if the channel - * supports it. If the channel does not support nested replies, ReplyToActivity falls back to SendToConversation. - * Use ReplyToActivity when replying to a specific activity in the conversation. - * Use SendToConversation in all other cases. - * - * @param conversationId Conversation ID - * @param activity Activity to send - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture sendToConversationAsync(String conversationId, Activity activity, - ServiceCallback serviceCallback); - /** * SendToConversation. * This method allows you to send an activity to the end of a conversation. @@ -308,26 +170,7 @@ ServiceFuture sendToConversationAsync(String conversationId, A * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the ResourceResponse object */ - Observable sendToConversationAsync(String conversationId, Activity activity); - - /** - * SendToConversation. - * This method allows you to send an activity to the end of a conversation. - * This is slightly different from ReplyToActivity(). - * SendToConverstion(conversationId) - will append the activity to the end of the conversation according to the - * timestamp or semantics of the channel. - * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply to another activity, if the channel - * supports it. If the channel does not support nested replies, ReplyToActivity falls back to SendToConversation. - * Use ReplyToActivity when replying to a specific activity in the conversation. - * Use SendToConversation in all other cases. - * - * @param conversationId Conversation ID - * @param activity Activity to send - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the ResourceResponse object - */ - Observable> sendToConversationWithServiceResponseAsync( - String conversationId, Activity activity); + CompletableFuture sendToConversationAsync(String conversationId, Activity activity); /** * UpdateActivity. @@ -344,38 +187,6 @@ Observable> sendToConversationWithServiceRespo */ ResourceResponse updateActivity(String conversationId, String activityId, Activity activity); - /** - * UpdateActivity. - * Edit an existing activity. - * Some channels allow you to edit an existing activity to reflect the new state of a bot conversation. - * For example, you can remove buttons after someone has clicked "Approve" button. - * - * @param conversationId Conversation ID - * @param activityId activityId to update - * @param activity replacement Activity - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture updateActivityAsync(String conversationId, - String activityId, - Activity activity, - ServiceCallback serviceCallback); - - /** - * UpdateActivity. - * Edit an existing activity. - * Some channels allow you to edit an existing activity to reflect the new state of a bot conversation. - * For example, you can remove buttons after someone has clicked "Approve" button. - * - * @param conversationId Conversation ID - * @param activityId activityId to update - * @param activity replacement Activity - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the ResourceResponse object - */ - Observable updateActivityAsync(String conversationId, String activityId, Activity activity); - /** * UpdateActivity. * Edit an existing activity. @@ -388,9 +199,7 @@ ServiceFuture updateActivityAsync(String conversationId, * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the ResourceResponse object */ - Observable> updateActivityWithServiceResponseAsync(String conversationId, - String activityId, - Activity activity); + CompletableFuture updateActivityAsync(String conversationId, String activityId, Activity activity); /** * ReplyToActivity. @@ -412,48 +221,6 @@ Observable> updateActivityWithServiceResponseA */ ResourceResponse replyToActivity(String conversationId, String activityId, Activity activity); - /** - * ReplyToActivity. - * This method allows you to reply to an activity. - * This is slightly different from SendToConversation(). - * SendToConverstion(conversationId) - will append the activity to the end of the conversation according to the - * timestamp or semantics of the channel. - * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply to another activity, if the channel - * supports it. If the channel does not support nested replies, ReplyToActivity falls back to SendToConversation. - * Use ReplyToActivity when replying to a specific activity in the conversation. - * Use SendToConversation in all other cases. - * - * @param conversationId Conversation ID - * @param activityId activityId the reply is to (OPTIONAL) - * @param activity Activity to send - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture replyToActivityAsync(String conversationId, - String activityId, - Activity activity, - ServiceCallback serviceCallback); - - /** - * ReplyToActivity. - * This method allows you to reply to an activity. - * This is slightly different from SendToConversation(). - * SendToConverstion(conversationId) - will append the activity to the end of the conversation according to the - * timestamp or semantics of the channel. - * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply to another activity, if the channel - * supports it. If the channel does not support nested replies, ReplyToActivity falls back to SendToConversation. - * Use ReplyToActivity when replying to a specific activity in the conversation. - * Use SendToConversation in all other cases. - * - * @param conversationId Conversation ID - * @param activityId activityId the reply is to (OPTIONAL) - * @param activity Activity to send - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the ResourceResponse object - */ - Observable replyToActivityAsync(String conversationId, String activityId, Activity activity); - /** * ReplyToActivity. * This method allows you to reply to an activity. @@ -471,8 +238,7 @@ ServiceFuture replyToActivityAsync(String conversationId, * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the ResourceResponse object */ - Observable> replyToActivityWithServiceResponseAsync( - String conversationId, String activityId, Activity activity); + CompletableFuture replyToActivityAsync(String conversationId, String activityId, Activity activity); /** * DeleteActivity. @@ -487,22 +253,6 @@ Observable> replyToActivityWithServiceResponse */ void deleteActivity(String conversationId, String activityId); - /** - * DeleteActivity. - * Delete an existing activity. - * Some channels allow you to delete an existing activity, and if successful this method will remove the - * specified activity. - * - * @param conversationId Conversation ID - * @param activityId activityId to delete - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture deleteActivityAsync(String conversationId, - String activityId, - ServiceCallback serviceCallback); - /** * DeleteActivity. * Delete an existing activity. @@ -514,20 +264,7 @@ ServiceFuture deleteActivityAsync(String conversationId, * @throws IllegalArgumentException thrown if parameters fail the validation * @return the {@link ServiceResponse} object if successful. */ - Observable deleteActivityAsync(String conversationId, String activityId); - - /** - * DeleteActivity. - * Delete an existing activity. - * Some channels allow you to delete an existing activity, and if successful this method will remove the specified - * activity. - * - * @param conversationId Conversation ID - * @param activityId activityId to delete - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceResponse} object if successful. - */ - Observable> deleteActivityWithServiceResponseAsync(String conversationId, String activityId); + CompletableFuture deleteActivityAsync(String conversationId, String activityId); /** * GetConversationMembers. @@ -549,37 +286,10 @@ ServiceFuture deleteActivityAsync(String conversationId, * of the conversation. * * @param conversationId Conversation ID - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture> getConversationMembersAsync( - String conversationId, ServiceCallback> serviceCallback); - - /** - * GetConversationMembers. - * Enumerate the members of a converstion. - * This REST API takes a ConversationId and returns an array of ChannelAccount objects representing the members - * of the conversation. - * - * @param conversationId Conversation ID - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the List<ChannelAccount> object - */ - Observable> getConversationMembersAsync(String conversationId); - - /** - * GetConversationMembers. - * Enumerate the members of a conversation. - * This REST API takes a ConversationId and returns an array of ChannelAccount objects representing the members - * of the conversation. - * - * @param conversationId Conversation ID * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the List<ChannelAccount> object */ - Observable>> getConversationMembersWithServiceResponseAsync( - String conversationId); + CompletableFuture> getConversationMembersAsync(String conversationId); /** * DeleteConversationMember. @@ -594,36 +304,6 @@ Observable>> getConversationMembersWithServ */ void deleteConversationMember(String conversationId, String memberId); - /** - * DeleteConversationMember. - * Deletes a member from a conversation. - * This REST API takes a ConversationId and a memberId (of type string) and removes that member from the - * conversation. If that member was the last member - * of the conversation, the conversation will also be deleted. - * - * @param conversationId Conversation ID - * @param memberId ID of the member to delete from this conversation - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture deleteConversationMemberAsync(String conversationId, - String memberId, - ServiceCallback serviceCallback); - - /** - * DeleteConversationMember. - * Deletes a member from a conversation. - * This REST API takes a ConversationId and a memberId (of type string) and removes that member from the - * conversation. If that member was the last member of the conversation, the conversation will also be deleted. - * - * @param conversationId Conversation ID - * @param memberId ID of the member to delete from this conversation - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceResponse} object if successful. - */ - Observable deleteConversationMemberAsync(String conversationId, String memberId); - /** * DeleteConversationMember. * Deletes a member from a conversation. @@ -635,8 +315,7 @@ ServiceFuture deleteConversationMemberAsync(String conversationId, * @throws IllegalArgumentException thrown if parameters fail the validation * @return the {@link ServiceResponse} object if successful. */ - Observable> deleteConversationMemberWithServiceResponseAsync( - String conversationId, String memberId); + CompletableFuture deleteConversationMemberAsync(String conversationId, String memberId); /** * GetActivityMembers. @@ -652,21 +331,6 @@ Observable> deleteConversationMemberWithServiceResponseAsy */ List getActivityMembers(String conversationId, String activityId); - /** - * GetActivityMembers. - * Enumerate the members of an activity. - * This REST API takes a ConversationId and a ActivityId, returning an array of ChannelAccount objects - * representing the members of the particular activity in the conversation. - * - * @param conversationId Conversation ID - * @param activityId Activity ID - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture> getActivityMembersAsync( - String conversationId, String activityId, ServiceCallback> serviceCallback); - /** * GetActivityMembers. * Enumerate the members of an activity. @@ -678,21 +342,7 @@ ServiceFuture> getActivityMembersAsync( * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the List<ChannelAccount> object */ - Observable> getActivityMembersAsync(String conversationId, String activityId); - - /** - * GetActivityMembers. - * Enumerate the members of an activity. - * This REST API takes a ConversationId and a ActivityId, returning an array of ChannelAccount objects - * representing the members of the particular activity in the conversation. - * - * @param conversationId Conversation ID - * @param activityId Activity ID - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the List<ChannelAccount> object - */ - Observable>> getActivityMembersWithServiceResponseAsync( - String conversationId, String activityId); + CompletableFuture> getActivityMembersAsync(String conversationId, String activityId); /** * UploadAttachment. @@ -709,38 +359,6 @@ Observable>> getActivityMembersWithServiceR */ ResourceResponse uploadAttachment(String conversationId, AttachmentData attachmentUpload); - /** - * UploadAttachment. - * Upload an attachment directly into a channel's blob storage. - * This is useful because it allows you to store data in a compliant store when dealing with enterprises. - * The response is a ResourceResponse which contains an AttachmentId which is suitable for using with the - * attachments API. - * - * @param conversationId Conversation ID - * @param attachmentUpload Attachment data - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - ServiceFuture uploadAttachmentAsync( - String conversationId, - AttachmentData attachmentUpload, - ServiceCallback serviceCallback); - - /** - * UploadAttachment. - * Upload an attachment directly into a channel's blob storage. - * This is useful because it allows you to store data in a compliant store when dealing with enterprises. - * The response is a ResourceResponse which contains an AttachmentId which is suitable for using with the - * attachments API. - * - * @param conversationId Conversation ID - * @param attachmentUpload Attachment data - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the ResourceResponse object - */ - Observable uploadAttachmentAsync(String conversationId, AttachmentData attachmentUpload); - /** * UploadAttachment. * Upload an attachment directly into a channel's blob storage. @@ -753,9 +371,7 @@ ServiceFuture uploadAttachmentAsync( * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the ResourceResponse object */ - Observable> uploadAttachmentWithServiceResponseAsync( - String conversationId, AttachmentData attachmentUpload); - + CompletableFuture uploadAttachmentAsync(String conversationId, AttachmentData attachmentUpload); /** * This method allows you to upload the historic activities to the conversation. @@ -772,38 +388,6 @@ Observable> uploadAttachmentWithServiceRespons */ ResourceResponse sendConversationHistory(String conversationId, Transcript history); - /** - * This method allows you to upload the historic activities to the conversation. - * - * Sender must ensure that the historic activities have unique ids and appropriate timestamps. - * The ids are used by the client to deal with duplicate activities and the timestamps are used by - * the client to render the activities in the right order. - * - * @param conversationId Conversation ID - * @param history Historic activities - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent - * @return the ResourceResponse object if successful. - */ - ServiceFuture sendConversationHistoryAsync( - String conversationId, Transcript history, ServiceCallback serviceCallback); - - /** - * This method allows you to upload the historic activities to the conversation. - * - * Sender must ensure that the historic activities have unique ids and appropriate timestamps. - * The ids are used by the client to deal with duplicate activities and the timestamps are used by - * the client to render the activities in the right order. - * - * @param conversationId Conversation ID - * @param history Historic activities - * @throws IllegalArgumentException thrown if parameters fail the validation - * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent - * @return the ResourceResponse object if successful. - */ - Observable sendConversationHistoryAsync(String conversationId, Transcript history); - /** * This method allows you to upload the historic activities to the conversation. * @@ -817,8 +401,7 @@ ServiceFuture sendConversationHistoryAsync( * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent * @return the ResourceResponse object if successful. */ - Observable> sendConversationHistoryWithServiceResponseAsync( - String conversationId, Transcript history); + CompletableFuture sendConversationHistoryAsync(String conversationId, Transcript history); /** * Enumerate the members of a conversation one page at a time. @@ -858,56 +441,9 @@ Observable> sendConversationHistoryWithService * from a previous request. * * @param conversationId Conversation ID - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent * @return the PagedMembersResult object if successful. */ - ServiceFuture getConversationPagedMembersAsync( - String conversationId, ServiceCallback serviceCallback); - - /** - * Enumerate the members of a conversation one page at a time. - * - * This REST API takes a ConversationId. Optionally a pageSize and/or continuationToken can be provided. - * It returns a PagedMembersResult, which contains an array of ChannelAccounts representing the members - * of the conversation and a continuation token that can be used to get more values. - * - * One page of ChannelAccounts records are returned with each call. The number of records in a page may - * vary between channels and calls. The pageSize parameter can be used as a suggestion. If there are no - * additional results the response will not contain a continuation token. If there are no members in the - * conversation the Members will be empty or not present in the response. - * - * A response to a request that has a continuation token from a prior request may rarely return members - * from a previous request. - * - * @param conversationId Conversation ID - * @throws IllegalArgumentException thrown if parameters fail the validation - * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent - * @return the PagedMembersResult object if successful. - */ - Observable getConversationPagedMembersAsync(String conversationId); - - /** - * Enumerate the members of a conversation one page at a time. - * - * This REST API takes a ConversationId. Optionally a pageSize and/or continuationToken can be provided. - * It returns a PagedMembersResult, which contains an array of ChannelAccounts representing the members - * of the conversation and a continuation token that can be used to get more values. - * - * One page of ChannelAccounts records are returned with each call. The number of records in a page may - * vary between channels and calls. The pageSize parameter can be used as a suggestion. If there are no - * additional results the response will not contain a continuation token. If there are no members in the - * conversation the Members will be empty or not present in the response. - * - * A response to a request that has a continuation token from a prior request may rarely return members - * from a previous request. - * - * @param conversationId Conversation ID - * @throws IllegalArgumentException thrown if parameters fail the validation - * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent - * @return the observable to the ResourceResponse object - */ - Observable> getConversationPagedMembersWithServiceResponseAsync( - String conversationId); + CompletableFuture getConversationPagedMembersAsync(String conversationId); } diff --git a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestAttachments.java b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestAttachments.java index 270031640..e79ccdd7b 100644 --- a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestAttachments.java +++ b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestAttachments.java @@ -10,11 +10,11 @@ import com.microsoft.bot.connector.Attachments; import com.google.common.reflect.TypeToken; import com.microsoft.bot.schema.AttachmentInfo; -import com.microsoft.rest.ServiceCallback; -import com.microsoft.rest.ServiceFuture; import com.microsoft.rest.ServiceResponse; import java.io.InputStream; import java.io.IOException; +import java.util.concurrent.CompletableFuture; + import okhttp3.ResponseBody; import retrofit2.http.GET; import retrofit2.http.Header; @@ -22,8 +22,6 @@ import retrofit2.http.Path; import retrofit2.http.Streaming; import retrofit2.Response; -import rx.functions.Func1; -import rx.Observable; /** * An instance of this class provides access to all the operations defined @@ -53,14 +51,14 @@ public class RestAttachments implements Attachments { interface AttachmentsService { @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Attachments getAttachmentInfo" }) @GET("v3/attachments/{attachmentId}") - Observable> getAttachmentInfo(@Path("attachmentId") String attachmentId, - @Header("accept-language") String acceptLanguage, - @Header("User-Agent") String userAgent); + CompletableFuture> getAttachmentInfo(@Path("attachmentId") String attachmentId, + @Header("accept-language") String acceptLanguage, + @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Attachments getAttachment" }) @GET("v3/attachments/{attachmentId}/views/{viewId}") @Streaming - Observable> getAttachment(@Path("attachmentId") String attachmentId, + CompletableFuture> getAttachment(@Path("attachmentId") String attachmentId, @Path("viewId") String viewId, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @@ -78,21 +76,7 @@ Observable> getAttachment(@Path("attachmentId") String at * @return the AttachmentInfo object if successful. */ public AttachmentInfo getAttachmentInfo(String attachmentId) { - return getAttachmentInfoWithServiceResponseAsync(attachmentId).toBlocking().single().body(); - } - - /** - * GetAttachmentInfo. - * Get AttachmentInfo structure describing the attachment views. - * - * @param attachmentId attachment id - * @param serviceCallback the async ServiceCallback to handle successful and failed responses. - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the {@link ServiceFuture} object - */ - public ServiceFuture getAttachmentInfoAsync( - String attachmentId, final ServiceCallback serviceCallback) { - return ServiceFuture.fromResponse(getAttachmentInfoWithServiceResponseAsync(attachmentId), serviceCallback); + return getAttachmentInfoAsync(attachmentId).join(); } /** @@ -103,29 +87,19 @@ public ServiceFuture getAttachmentInfoAsync( * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the AttachmentInfo object */ - public Observable getAttachmentInfoAsync(String attachmentId) { - return getAttachmentInfoWithServiceResponseAsync(attachmentId).map(response -> response.body()); - } - - /** - * GetAttachmentInfo. - * Get AttachmentInfo structure describing the attachment views. - * - * @param attachmentId attachment id - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the AttachmentInfo object - */ - public Observable> getAttachmentInfoWithServiceResponseAsync(String attachmentId) { + public CompletableFuture getAttachmentInfoAsync(String attachmentId) { if (attachmentId == null) { throw new IllegalArgumentException("Parameter attachmentId is required and cannot be null."); } + return service.getAttachmentInfo(attachmentId, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = getAttachmentInfoDelegate(response); - return Observable.just(clientResponse); + return getAttachmentInfoDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("getAttachmentInfoAsync", responseBodyResponse); } }); } @@ -151,36 +125,7 @@ private ServiceResponse getAttachmentInfoDelegate(Response getAttachmentAsync(String attachmentId, - String viewId, - final ServiceCallback serviceCallback) { - return ServiceFuture.fromResponse(getAttachmentWithServiceResponseAsync(attachmentId, viewId), serviceCallback); - } - - /** - * GetAttachment. - * Get the named view as binary content. - * - * @param attachmentId attachment id - * @param viewId View id from attachmentInfo - * @throws IllegalArgumentException thrown if parameters fail the validation - * @return the observable to the InputStream object - */ - public Observable getAttachmentAsync(String attachmentId, String viewId) { - return getAttachmentWithServiceResponseAsync(attachmentId, viewId).map(response -> response.body()); + return getAttachmentAsync(attachmentId, viewId).join(); } /** @@ -192,8 +137,7 @@ public Observable getAttachmentAsync(String attachmentId, String vi * @throws IllegalArgumentException thrown if parameters fail the validation * @return the observable to the InputStream object */ - public Observable> getAttachmentWithServiceResponseAsync(String attachmentId, - String viewId) { + public CompletableFuture getAttachmentAsync(String attachmentId, String viewId) { if (attachmentId == null) { throw new IllegalArgumentException("Parameter attachmentId is required and cannot be null."); } @@ -201,12 +145,13 @@ public Observable> getAttachmentWithServiceResponse throw new IllegalArgumentException("Parameter viewId is required and cannot be null."); } return service.getAttachment(attachmentId, viewId, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = getAttachmentDelegate(response); - return Observable.just(clientResponse); + return getAttachmentDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("getAttachmentAsync", responseBodyResponse); } }); } diff --git a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestConversations.java b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestConversations.java index b85a1e80b..c0c3f032f 100644 --- a/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestConversations.java +++ b/libraries/bot-connector/src/main/java/com/microsoft/bot/connector/rest/RestConversations.java @@ -10,12 +10,11 @@ import retrofit2.Retrofit; import com.microsoft.bot.connector.Conversations; import com.google.common.reflect.TypeToken; -import com.microsoft.rest.ServiceCallback; -import com.microsoft.rest.ServiceFuture; import com.microsoft.rest.ServiceResponse; import com.microsoft.rest.Validator; import java.io.IOException; import java.util.List; +import java.util.concurrent.CompletableFuture; import okhttp3.ResponseBody; import retrofit2.http.Body; @@ -28,8 +27,6 @@ import retrofit2.http.PUT; import retrofit2.http.Query; import retrofit2.Response; -import rx.functions.Func1; -import rx.Observable; /** * An instance of this class provides access to all the operations defined @@ -60,26 +57,26 @@ public class RestConversations implements Conversations { interface ConversationsService { @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations getConversations" }) @GET("v3/conversations") - Observable> getConversations(@Query("continuationToken") String continuationToken, + CompletableFuture> getConversations(@Query("continuationToken") String continuationToken, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations createConversation" }) @POST("v3/conversations") - Observable> createConversation(@Body ConversationParameters parameters, + CompletableFuture> createConversation(@Body ConversationParameters parameters, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations sendToConversation" }) @POST("v3/conversations/{conversationId}/activities") - Observable> sendToConversation(@Path("conversationId") String conversationId, + CompletableFuture> sendToConversation(@Path("conversationId") String conversationId, @Body Activity activity, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations updateActivity" }) @PUT("v3/conversations/{conversationId}/activities/{activityId}") - Observable> updateActivity(@Path("conversationId") String conversationId, + CompletableFuture> updateActivity(@Path("conversationId") String conversationId, @Path("activityId") String activityId, @Body Activity activity, @Header("accept-language") String acceptLanguage, @@ -87,7 +84,7 @@ Observable> updateActivity(@Path("conversationId") String @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations replyToActivity" }) @POST("v3/conversations/{conversationId}/activities/{activityId}") - Observable> replyToActivity(@Path("conversationId") String conversationId, + CompletableFuture> replyToActivity(@Path("conversationId") String conversationId, @Path("activityId") String activityId, @Body Activity activity, @Header("accept-language") String acceptLanguage, @@ -95,48 +92,48 @@ Observable> replyToActivity(@Path("conversationId") Strin @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations deleteActivity" }) @HTTP(path = "v3/conversations/{conversationId}/activities/{activityId}", method = "DELETE", hasBody = true) - Observable> deleteActivity(@Path("conversationId") String conversationId, + CompletableFuture> deleteActivity(@Path("conversationId") String conversationId, @Path("activityId") String activityId, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations getConversationMembers" }) @GET("v3/conversations/{conversationId}/members") - Observable> getConversationMembers(@Path("conversationId") String conversationId, + CompletableFuture> getConversationMembers(@Path("conversationId") String conversationId, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations deleteConversationMember" }) @HTTP(path = "v3/conversations/{conversationId}/members/{memberId}", method = "DELETE", hasBody = true) - Observable> deleteConversationMember(@Path("conversationId") String conversationId, + CompletableFuture> deleteConversationMember(@Path("conversationId") String conversationId, @Path("memberId") String memberId, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations getActivityMembers" }) @GET("v3/conversations/{conversationId}/activities/{activityId}/members") - Observable> getActivityMembers(@Path("conversationId") String conversationId, + CompletableFuture> getActivityMembers(@Path("conversationId") String conversationId, @Path("activityId") String activityId, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations uploadAttachment" }) @POST("v3/conversations/{conversationId}/attachments") - Observable> uploadAttachment(@Path("conversationId") String conversationId, + CompletableFuture> uploadAttachment(@Path("conversationId") String conversationId, @Body AttachmentData attachmentUpload, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations sendConversationHistory" }) @POST("v3/conversations/{conversationId}/activities/history") - Observable> sendConversationHistory(@Path("conversationId") String conversationId, + CompletableFuture> sendConversationHistory(@Path("conversationId") String conversationId, @Body Transcript history, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bot.schema.Conversations getConversationPagedMembers" }) @GET("v3/conversations/{conversationId}/pagedmembers") - Observable> getConversationPagedMembers(@Path("conversationId") String conversationId, + CompletableFuture> getConversationPagedMembers(@Path("conversationId") String conversationId, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent); } @@ -148,7 +145,7 @@ Observable> getConversationPagedMembers(@Path("conversati */ @Override public ConversationsResult getConversations() { - return getConversationsWithServiceResponseAsync().toBlocking().single().body(); + return getConversationsAsync().join(); } /** @@ -157,39 +154,8 @@ public ConversationsResult getConversations() { * @see Conversations#getConversationsAsync */ @Override - public ServiceFuture getConversationsAsync( - final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(getConversationsWithServiceResponseAsync(), serviceCallback); - } - - /** - * Implementation of getConversationsAsync. - * - * @see Conversations#getConversationsAsync - */ - @Override - public Observable getConversationsAsync() { - return getConversationsWithServiceResponseAsync().map(response -> response.body()); - } - - /** - * Implementation of getConversationsWithServiceResponseAsync. - * - * @see Conversations#getConversationsWithServiceResponseAsync - */ - @Override - public Observable> getConversationsWithServiceResponseAsync() { - final String continuationToken = null; - return service.getConversations(continuationToken, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { - try { - ServiceResponse clientResponse = getConversationsDelegate(response); - return Observable.just(clientResponse); - } catch (Throwable t) { - return Observable.error(t); - } - }); + public CompletableFuture getConversationsAsync() { + return getConversationsAsync(null); } /** @@ -199,19 +165,7 @@ public Observable> getConversationsWithServ */ @Override public ConversationsResult getConversations(String continuationToken) { - return getConversationsWithServiceResponseAsync(continuationToken).toBlocking().single().body(); - } - - /** - * Implementation of getConversationsAsync. - * - * @see Conversations#getConversationsAsync - */ - @Override - public ServiceFuture getConversationsAsync( - String continuationToken, final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(getConversationsWithServiceResponseAsync(continuationToken), serviceCallback); + return getConversationsAsync(continuationToken).join(); } /** @@ -220,29 +174,15 @@ public ServiceFuture getConversationsAsync( * @see Conversations#getConversationsAsync */ @Override - public Observable getConversationsAsync(String continuationToken) { - return getConversationsWithServiceResponseAsync(continuationToken).map(response -> response.body()); - } - - /** - * Implementation of getConversationsWithServiceResponseAsync. - * - * @see Conversations#getConversationsWithServiceResponseAsync - */ - @Override - public Observable> getConversationsWithServiceResponseAsync( - String continuationToken) { - + public CompletableFuture getConversationsAsync(String continuationToken) { return service.getConversations(continuationToken, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap(new Func1, Observable>>() { - @Override - public Observable> call(Response response) { - try { - ServiceResponse clientResponse = getConversationsDelegate(response); - return Observable.just(clientResponse); - } catch (Throwable t) { - return Observable.error(t); - } + .thenApply(responseBodyResponse -> { + try { + return getConversationsDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; + } catch (Throwable t) { + throw new ErrorResponseException("getConversationsAsync", responseBodyResponse); } }); } @@ -263,51 +203,29 @@ private ServiceResponse getConversationsDelegate( */ @Override public ConversationResourceResponse createConversation(ConversationParameters parameters) { - return createConversationWithServiceResponseAsync(parameters).toBlocking().single().body(); - } - - /** - * Implementation of CreateConversation. - * - * @see Conversations#createConversationAsync - */ - @Override - public ServiceFuture createConversationAsync( - ConversationParameters parameters, final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(createConversationWithServiceResponseAsync(parameters), serviceCallback); - } - - /** - * Implementation of CreateConversation. - * - * @see Conversations#createConversationAsync - */ - @Override - public Observable createConversationAsync(ConversationParameters parameters) { - return createConversationWithServiceResponseAsync(parameters).map(response -> response.body()); + return createConversationAsync(parameters).join(); } /** * Implementation of createConversationWithServiceResponseAsync. * - * @see Conversations#createConversationWithServiceResponseAsync + * @see Conversations#createConversationAsync */ @Override - public Observable> createConversationWithServiceResponseAsync( - ConversationParameters parameters) { - + public CompletableFuture createConversationAsync(ConversationParameters parameters) { if (parameters == null) { throw new IllegalArgumentException("Parameter parameters is required and cannot be null."); } Validator.validate(parameters); + return service.createConversation(parameters, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = createConversationDelegate(response); - return Observable.just(clientResponse); + return createConversationDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("createConversationAsync", responseBodyResponse); } }); } @@ -330,7 +248,7 @@ private ServiceResponse createConversationDelegate */ @Override public ResourceResponse sendToConversation(String conversationId, Activity activity) { - return sendToConversationWithServiceResponseAsync(conversationId, activity).toBlocking().single().body(); + return sendToConversationAsync(conversationId, activity).join(); } /** @@ -339,31 +257,7 @@ public ResourceResponse sendToConversation(String conversationId, Activity activ * @see Conversations#sendToConversationAsync */ @Override - public ServiceFuture sendToConversationAsync( - String conversationId, Activity activity, final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(sendToConversationWithServiceResponseAsync(conversationId, activity), serviceCallback); - } - - /** - * Implementation of sendToConversationAsync. - * - * @see Conversations#sendToConversationAsync - */ - @Override - public Observable sendToConversationAsync(String conversationId, Activity activity) { - return sendToConversationWithServiceResponseAsync(conversationId, activity).map(response -> response.body()); - } - - /** - * Implementation of sendToConversationWithServiceResponseAsync. - * - * @see Conversations#sendToConversationWithServiceResponseAsync - */ - @Override - public Observable> sendToConversationWithServiceResponseAsync( - String conversationId, Activity activity) { - + public CompletableFuture sendToConversationAsync(String conversationId, Activity activity) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } @@ -371,13 +265,15 @@ public Observable> sendToConversationWithServi throw new IllegalArgumentException("Parameter activity is required and cannot be null."); } Validator.validate(activity); + return service.sendToConversation(conversationId, activity, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = sendToConversationDelegate(response); - return Observable.just(clientResponse); + return sendToConversationDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("sendToConversationAsync", responseBodyResponse); } }); } @@ -400,22 +296,7 @@ private ServiceResponse sendToConversationDelegate( */ @Override public ResourceResponse updateActivity(String conversationId, String activityId, Activity activity) { - return updateActivityWithServiceResponseAsync(conversationId, activityId, activity).toBlocking().single().body(); - } - - /** - * Implementation of updateActivityAsync. - * - * @see Conversations#updateActivityAsync - */ - @Override - public ServiceFuture updateActivityAsync( - String conversationId, - String activityId, - Activity activity, - final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(updateActivityWithServiceResponseAsync(conversationId, activityId, activity), serviceCallback); + return updateActivityAsync(conversationId, activityId, activity).join(); } /** @@ -424,18 +305,7 @@ public ServiceFuture updateActivityAsync( * @see Conversations#updateActivityAsync */ @Override - public Observable updateActivityAsync(String conversationId, String activityId, Activity activity) { - return updateActivityWithServiceResponseAsync(conversationId, activityId, activity).map(response -> response.body()); - } - - /** - * Implementation of updateActivityWithServiceResponseAsync. - * - * @see Conversations#updateActivityWithServiceResponseAsync - */ - @Override - public Observable> updateActivityWithServiceResponseAsync( - String conversationId, String activityId, Activity activity) { + public CompletableFuture updateActivityAsync(String conversationId, String activityId, Activity activity) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } @@ -446,13 +316,15 @@ public Observable> updateActivityWithServiceRe throw new IllegalArgumentException("Parameter activity is required and cannot be null."); } Validator.validate(activity); + return service.updateActivity(conversationId, activityId, activity, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = updateActivityDelegate(response); - return Observable.just(clientResponse); + return updateActivityDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("updateActivityAsync", responseBodyResponse); } }); } @@ -475,24 +347,7 @@ private ServiceResponse updateActivityDelegate( */ @Override public ResourceResponse replyToActivity(String conversationId, String activityId, Activity activity) { - return replyToActivityWithServiceResponseAsync( - conversationId, activityId, activity).toBlocking().single().body(); - } - - /** - * Implementation of replyToActivityAsync. - * - * @see Conversations#replyToActivityAsync - */ - @Override - public ServiceFuture replyToActivityAsync( - String conversationId, - String activityId, - Activity activity, - final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(replyToActivityWithServiceResponseAsync( - conversationId, activityId, activity), serviceCallback); + return replyToActivityAsync(conversationId, activityId, activity).join(); } /** @@ -501,21 +356,9 @@ public ServiceFuture replyToActivityAsync( * @see Conversations#replyToActivityAsync */ @Override - public Observable replyToActivityAsync(String conversationId, + public CompletableFuture replyToActivityAsync(String conversationId, String activityId, Activity activity) { - return replyToActivityWithServiceResponseAsync(conversationId, activityId, activity).map(response -> response.body()); - } - - /** - * Implementation of replyToActivityWithServiceResponseAsync. - * - * @see Conversations#replyToActivityWithServiceResponseAsync - */ - @Override - public Observable> replyToActivityWithServiceResponseAsync( - String conversationId, String activityId, Activity activity) { - if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } @@ -526,13 +369,15 @@ public Observable> replyToActivityWithServiceR throw new IllegalArgumentException("Parameter activity is required and cannot be null."); } Validator.validate(activity); + return service.replyToActivity(conversationId, activityId, activity, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = replyToActivityDelegate(response); - return Observable.just(clientResponse); + return replyToActivityDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("replyToActivityAsync", responseBodyResponse); } }); } @@ -555,53 +400,31 @@ private ServiceResponse replyToActivityDelegate( */ @Override public void deleteActivity(String conversationId, String activityId) { - deleteActivityWithServiceResponseAsync(conversationId, activityId).toBlocking().single().body(); - } - - /** - * Implementation of deleteActivityAsync. - * - * @see Conversations#deleteActivityAsync - */ - @Override - public ServiceFuture deleteActivityAsync( - String conversationId, String activityId, final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(deleteActivityWithServiceResponseAsync(conversationId, activityId), serviceCallback); - } - - /** - * Implementation of deleteActivityAsync. - * - * @see Conversations#deleteActivityAsync - */ - @Override - public Observable deleteActivityAsync(String conversationId, String activityId) { - return deleteActivityWithServiceResponseAsync(conversationId, activityId).map(response -> response.body()); + deleteActivityAsync(conversationId, activityId).join(); } /** * Implementation of deleteActivityWithServiceResponseAsync. * - * @see Conversations#deleteActivityWithServiceResponseAsync + * @see Conversations#deleteActivityAsync */ @Override - public Observable> deleteActivityWithServiceResponseAsync( - String conversationId, String activityId) { - + public CompletableFuture deleteActivityAsync(String conversationId, String activityId) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } if (activityId == null) { throw new IllegalArgumentException("Parameter activityId is required and cannot be null."); } + return service.deleteActivity(conversationId, activityId, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = deleteActivityDelegate(response); - return Observable.just(clientResponse); + return deleteActivityDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("deleteActivityAsync", responseBodyResponse); } }); } @@ -623,7 +446,7 @@ private ServiceResponse deleteActivityDelegate( */ @Override public List getConversationMembers(String conversationId) { - return getConversationMembersWithServiceResponseAsync(conversationId).toBlocking().single().body(); + return getConversationMembersAsync(conversationId).join(); } /** @@ -632,41 +455,18 @@ public List getConversationMembers(String conversationId) { * @see Conversations#getConversationMembersAsync */ @Override - public ServiceFuture> getConversationMembersAsync( - String conversationId, final ServiceCallback> serviceCallback) { - - return ServiceFuture.fromResponse(getConversationMembersWithServiceResponseAsync(conversationId), serviceCallback); - } - - /** - * Implementation of getConversationMembersAsync. - * - * @see Conversations#getConversationMembersAsync - */ - @Override - public Observable> getConversationMembersAsync(String conversationId) { - return getConversationMembersWithServiceResponseAsync(conversationId).map(response -> response.body()); - } - - /** - * Implementation of getConversationMembersWithServiceResponseAsync. - * - * @see Conversations#getConversationMembersWithServiceResponseAsync - */ - @Override - public Observable>> getConversationMembersWithServiceResponseAsync( - String conversationId) { - + public CompletableFuture> getConversationMembersAsync(String conversationId) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } return service.getConversationMembers(conversationId, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse> clientResponse = getConversationMembersDelegate(response); - return Observable.just(clientResponse); + return getConversationMembersDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("getConversationMembersAsync", responseBodyResponse); } }); } @@ -687,55 +487,31 @@ private ServiceResponse> getConversationMembersDelegate( */ @Override public void deleteConversationMember(String conversationId, String memberId) { - deleteConversationMemberWithServiceResponseAsync(conversationId, memberId).toBlocking().single().body(); - } - - /** - * Implementation of deleteConversationMemberAsync. - * - * @see Conversations#deleteConversationMemberAsync - */ - @Override - public ServiceFuture deleteConversationMemberAsync( - String conversationId, String memberId, final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(deleteConversationMemberWithServiceResponseAsync( - conversationId, memberId), serviceCallback); - } - - /** - * Implementation of deleteConversationMemberAsync. - * - * @see Conversations#deleteConversationMemberAsync - */ - @Override - public Observable deleteConversationMemberAsync(String conversationId, String memberId) { - return deleteConversationMemberWithServiceResponseAsync( - conversationId, memberId).map(response -> response.body()); + deleteConversationMemberAsync(conversationId, memberId).join(); } /** * Implementation of deleteConversationMemberWithServiceResponseAsync. * - * @see Conversations#deleteConversationMemberWithServiceResponseAsync + * @see Conversations#deleteConversationMemberAsync */ @Override - public Observable> deleteConversationMemberWithServiceResponseAsync( - String conversationId, String memberId) { - + public CompletableFuture deleteConversationMemberAsync(String conversationId, String memberId) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } if (memberId == null) { throw new IllegalArgumentException("Parameter memberId is required and cannot be null."); } + return service.deleteConversationMember(conversationId, memberId, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = deleteConversationMemberDelegate(response); - return Observable.just(clientResponse); + return deleteConversationMemberDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("deleteConversationMemberAsync", responseBodyResponse); } }); } @@ -758,19 +534,7 @@ private ServiceResponse deleteConversationMemberDelegate( */ @Override public List getActivityMembers(String conversationId, String activityId) { - return getActivityMembersWithServiceResponseAsync(conversationId, activityId).toBlocking().single().body(); - } - - /** - * Implementation of getActivityMembersAsync. - * - * @see Conversations#getActivityMembersAsync - */ - @Override - public ServiceFuture> getActivityMembersAsync( - String conversationId, String activityId, final ServiceCallback> serviceCallback) { - - return ServiceFuture.fromResponse(getActivityMembersWithServiceResponseAsync(conversationId, activityId), serviceCallback); + return getActivityMembersAsync(conversationId, activityId).join(); } /** @@ -779,32 +543,22 @@ public ServiceFuture> getActivityMembersAsync( * @see Conversations#getActivityMembersAsync */ @Override - public Observable> getActivityMembersAsync(String conversationId, String activityId) { - return getActivityMembersWithServiceResponseAsync(conversationId, activityId).map(response -> response.body()); - } - - /** - * Implementation of getActivityMembersWithServiceResponseAsync. - * - * @see Conversations#getActivityMembersWithServiceResponseAsync - */ - @Override - public Observable>> getActivityMembersWithServiceResponseAsync( - String conversationId, String activityId) { - + public CompletableFuture> getActivityMembersAsync(String conversationId, String activityId) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } if (activityId == null) { throw new IllegalArgumentException("Parameter activityId is required and cannot be null."); } + return service.getActivityMembers(conversationId, activityId, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse> clientResponse = getActivityMembersDelegate(response); - return Observable.just(clientResponse); + return getActivityMembersDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("getActivityMembersAsync", responseBodyResponse); } }); } @@ -825,19 +579,7 @@ private ServiceResponse> getActivityMembersDelegate( */ @Override public ResourceResponse uploadAttachment(String conversationId, AttachmentData attachmentUpload) { - return uploadAttachmentWithServiceResponseAsync(conversationId, attachmentUpload).toBlocking().single().body(); - } - - /** - * Implementation of uploadAttachmentAsync. - * - * @see Conversations#uploadAttachmentAsync - */ - @Override - public ServiceFuture uploadAttachmentAsync( - String conversationId, AttachmentData attachmentUpload, final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(uploadAttachmentWithServiceResponseAsync(conversationId, attachmentUpload), serviceCallback); + return uploadAttachmentAsync(conversationId, attachmentUpload).join(); } /** @@ -846,20 +588,7 @@ public ServiceFuture uploadAttachmentAsync( * @see Conversations#uploadAttachmentAsync */ @Override - public Observable uploadAttachmentAsync(String conversationId, AttachmentData attachmentUpload) { - return uploadAttachmentWithServiceResponseAsync( - conversationId, attachmentUpload).map(response -> response.body()); - } - - /** - * Implementation of uploadAttachmentWithServiceResponseAsync. - * - * @see Conversations#uploadAttachmentWithServiceResponseAsync - */ - @Override - public Observable> uploadAttachmentWithServiceResponseAsync( - String conversationId, AttachmentData attachmentUpload) { - + public CompletableFuture uploadAttachmentAsync(String conversationId, AttachmentData attachmentUpload) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } @@ -867,13 +596,15 @@ public Observable> uploadAttachmentWithService throw new IllegalArgumentException("Parameter attachmentUpload is required and cannot be null."); } Validator.validate(attachmentUpload); + return service.uploadAttachment(conversationId, attachmentUpload, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = uploadAttachmentDelegate(response); - return Observable.just(clientResponse); + return uploadAttachmentDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("uploadAttachmentAsync", responseBodyResponse); } }); } @@ -897,19 +628,7 @@ private ServiceResponse uploadAttachmentDelegate( */ @Override public ResourceResponse sendConversationHistory(String conversationId, Transcript history) { - return sendConversationHistoryWithServiceResponseAsync(conversationId, history).toBlocking().single().body(); - } - - /** - * Implementation of sendConversationHistoryAsync. - * - * @see Conversations#sendConversationHistoryAsync - */ - @Override - public ServiceFuture sendConversationHistoryAsync( - String conversationId, Transcript history, final ServiceCallback serviceCallback) { - - return ServiceFuture.fromResponse(sendConversationHistoryWithServiceResponseAsync(conversationId, history), serviceCallback); + return sendConversationHistoryAsync(conversationId, history).join(); } /** @@ -918,20 +637,7 @@ public ServiceFuture sendConversationHistoryAsync( * @see Conversations#sendConversationHistoryAsync */ @Override - public Observable sendConversationHistoryAsync(String conversationId, Transcript history) { - return sendConversationHistoryWithServiceResponseAsync( - conversationId, history).map(response -> response.body()); - } - - /** - * Implementation of sendConversationHistoryWithServiceResponseAsync. - * - * @see Conversations#sendConversationHistoryWithServiceResponseAsync - */ - @Override - public Observable> sendConversationHistoryWithServiceResponseAsync( - String conversationId, Transcript history) { - + public CompletableFuture sendConversationHistoryAsync(String conversationId, Transcript history) { if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } @@ -939,13 +645,15 @@ public Observable> sendConversationHistoryWith throw new IllegalArgumentException("Parameter history is required and cannot be null."); } Validator.validate(history); + return service.sendConversationHistory(conversationId, history, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = sendConversationHistoryDelegate(response); - return Observable.just(clientResponse); + return sendConversationHistoryDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("sendConversationHistoryAsync", responseBodyResponse); } }); } @@ -969,19 +677,7 @@ private ServiceResponse sendConversationHistoryDelegate( */ @Override public PagedMembersResult getConversationPagedMembers(String conversationId){ - return getConversationPagedMembersWithServiceResponseAsync(conversationId).toBlocking().single().body(); - } - - /** - * Implementation of getConversationPagedMembersAsync. - * - * @see Conversations#getConversationPagedMembersAsync - */ - @Override - public ServiceFuture getConversationPagedMembersAsync( - String conversationId, final ServiceCallback serviceCallback){ - - return ServiceFuture.fromResponse(getConversationPagedMembersWithServiceResponseAsync(conversationId), serviceCallback); + return getConversationPagedMembersAsync(conversationId).join(); } /** @@ -990,29 +686,19 @@ public ServiceFuture getConversationPagedMembersAsync( * @see Conversations#getConversationPagedMembersAsync */ @Override - public Observable getConversationPagedMembersAsync(String conversationId){ - return getConversationPagedMembersWithServiceResponseAsync(conversationId).map(response -> response.body()); - } - - /** - * Implementation of getConversationPagedMembersWithServiceResponseAsync. - * - * @see Conversations#getConversationPagedMembersWithServiceResponseAsync - */ - @Override - public Observable> getConversationPagedMembersWithServiceResponseAsync( - String conversationId){ - + public CompletableFuture getConversationPagedMembersAsync(String conversationId){ if (conversationId == null) { throw new IllegalArgumentException("Parameter conversationId is required and cannot be null."); } + return service.getConversationPagedMembers(conversationId, this.client.getAcceptLanguage(), this.client.getUserAgent()) - .flatMap((Func1, Observable>>) response -> { + .thenApply(responseBodyResponse -> { try { - ServiceResponse clientResponse = getConversationPagedMembersDelegate(response); - return Observable.just(clientResponse); + return getConversationPagedMembersDelegate(responseBodyResponse).body(); + } catch (ErrorResponseException e) { + throw e; } catch (Throwable t) { - return Observable.error(t); + throw new ErrorResponseException("getConversationPagedMembersAsync", responseBodyResponse); } }); } diff --git a/libraries/bot-connector/src/test/java/com/microsoft/bot/connector/ConversationsTest.java b/libraries/bot-connector/src/test/java/com/microsoft/bot/connector/ConversationsTest.java index 8ca761caf..e41020cdb 100644 --- a/libraries/bot-connector/src/test/java/com/microsoft/bot/connector/ConversationsTest.java +++ b/libraries/bot-connector/src/test/java/com/microsoft/bot/connector/ConversationsTest.java @@ -10,9 +10,11 @@ import java.io.File; import java.io.FileInputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.concurrent.CompletionException; public class ConversationsTest extends BotConnectorTestBase { @@ -54,10 +56,14 @@ public void CreateConversationWithInvalidBot() { try { ConversationResourceResponse result = connector.getConversations().createConversation(params); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("ServiceError", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().startsWith("Invalid userId")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("ServiceError", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().startsWith("Invalid userId")); + } else { + throw e; + } } } @@ -78,10 +84,14 @@ public void CreateConversationWithoutMembers() { try { ConversationResourceResponse result = connector.getConversations().createConversation(params); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("BadArgument", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().startsWith("Conversations")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("BadArgument", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().startsWith("Conversations")); + } else { + throw e; + } } } @@ -102,9 +112,19 @@ public void CreateConversationWithBotMember() { try { ConversationResourceResponse result = connector.getConversations().createConversation(params); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("BadArgument", e.body().getError().getCode().toString()); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + Assert.assertEquals("BadArgument", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + } + } + + @Test + public void CreateConversationWithNullParameter() { + try { + ConversationResourceResponse result = connector.getConversations().createConversation(null); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); } } @@ -142,10 +162,24 @@ public void GetConversationMembersWithInvalidConversationId() { try { List members = connector.getConversations().getConversationMembers(conversation.getId().concat("M")); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("ServiceError", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().contains("The specified channel was not found")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("ServiceError", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().contains("The specified channel was not found")); + } else { + throw e; + } + } + } + + @Test + public void GetConversationMembersWithNullConversationId() { + try { + List members = connector.getConversations().getConversationMembers(null); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); } } @@ -174,6 +208,34 @@ public void GetConversationPagedMembers() { } } + @Test + public void GetConversationPagedMembersWithInvalidConversationId() { + Activity activity = new Activity(ActivityTypes.MESSAGE) {{ + setRecipient(user); + setFrom(bot); + setText("TEST Get Activity Members"); + }}; + + ConversationParameters createMessage = new ConversationParameters() {{ + setMembers(Collections.singletonList(user)); + setBot(bot); + setActivity(activity); + }}; + + ConversationResourceResponse conversation = connector.getConversations().createConversation(createMessage); + + try { + connector.getConversations().getConversationPagedMembers(conversation.getId().concat("M")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals(400, ((ErrorResponseException)e.getCause()).response().code()); + } else { + throw e; + } + } + } + @Test public void SendToConversation() { @@ -215,10 +277,14 @@ public void SendToConversationWithInvalidConversationId() { try { ResourceResponse response = connector.getConversations().sendToConversation(conversation.getId().concat("M"), activity); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("ServiceError", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().contains("The specified channel was not found")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("ServiceError", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().contains("The specified channel was not found")); + } else { + throw e; + } } } @@ -242,13 +308,44 @@ public void SendToConversationWithInvalidBotId() { try { ResourceResponse response = connector.getConversations().sendToConversation(conversation.getId(), activity); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("MissingProperty", e.body().getError().getCode().toString()); - Assert.assertEquals("The bot referenced by the 'from' field is unrecognized", e.body().getError().getMessage()); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("MissingProperty", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertEquals("The bot referenced by the 'from' field is unrecognized", ((ErrorResponseException)e.getCause()).body().getError().getMessage()); + } else { + throw e; + } + } + } + + @Test + public void SendToConversationWithNullConversationId() { + Activity activity = new Activity(ActivityTypes.MESSAGE) {{ + setRecipient(user); + setFrom(bot); + setText("TEST Send to Conversation with null conversation id"); + }}; + + try { + connector.getConversations().sendToConversation(null, activity); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void SendToConversationWithNullActivity() { + try { + connector.getConversations().sendToConversation("id",null); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); } } + @Test public void SendCardToConversation() { @@ -341,10 +438,34 @@ public void GetActivityMembersWithInvalidConversationId() { try { List members = connector.getConversations().getActivityMembers(conversation.getId().concat("M"), conversation.getActivityId()); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("ServiceError", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().contains("The specified channel was not found")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("ServiceError", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().contains("The specified channel was not found")); + } else { + throw e; + } + } + } + + @Test + public void GetActivityMembersWithNullConversationId() { + try { + connector.getConversations().getActivityMembers(null, "id"); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void GetActivityMembersWithNullActivityId() { + try { + connector.getConversations().getActivityMembers("id", null); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); } } @@ -403,10 +524,81 @@ public void ReplyToActivityWithInvalidConversationId() { try { ResourceResponse replyResponse = connector.getConversations().replyToActivity(conversation.getId().concat("M"), response.getId(), reply); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("ServiceError", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().contains("The specified channel was not found")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("ServiceError", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().contains("The specified channel was not found")); + } else { + throw e; + } + } + } + + @Test + public void ReplyToActivityWithNullConversationId() { + Activity activity = new Activity(ActivityTypes.MESSAGE) {{ + setRecipient(user); + setFrom(bot); + setText("TEST Reply activity with null conversation id"); + }}; + + try { + connector.getConversations().replyToActivity(null, "id", activity); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void ReplyToActivityWithNullActivityId() { + Activity activity = new Activity(ActivityTypes.MESSAGE) {{ + setRecipient(user); + setFrom(bot); + setText("TEST Reply activity with null activity id"); + }}; + + try { + connector.getConversations().replyToActivity("id", null, activity); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void ReplyToActivityWithNullActivity() { + try { + connector.getConversations().replyToActivity("id", "id", null); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void ReplyToActivityWithNullReply() { + Activity activity = new Activity(ActivityTypes.MESSAGE) {{ + setRecipient(user); + setFrom(bot); + setText("TEST Reply activity with null reply"); + }}; + + ConversationParameters createMessage = new ConversationParameters() {{ + setMembers(Collections.singletonList(user)); + setBot(bot); + }}; + + ConversationResourceResponse conversation = connector.getConversations().createConversation(createMessage); + + ResourceResponse response = connector.getConversations().sendToConversation(conversation.getId(), activity); + + try { + ResourceResponse replyResponse = connector.getConversations().replyToActivity(conversation.getId(), response.getId(), null); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); } } @@ -451,10 +643,34 @@ public void DeleteActivityWithInvalidConversationId() { try { connector.getConversations().deleteActivity("B21S8SG7K:T03CWQ0QB", conversation.getActivityId()); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("ServiceError", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().contains("Invalid ConversationId")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("ServiceError", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().contains("Invalid ConversationId")); + } else { + throw e; + } + } + } + + @Test + public void DeleteActivityWithNullConversationId() { + try { + connector.getConversations().deleteActivity(null, "id"); + Assert.fail("expected exception did not occur."); + } catch(IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void DeleteActivityWithNullActivityId() { + try { + connector.getConversations().deleteActivity("id", null); + Assert.fail("expected exception did not occur."); + } catch(IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); } } @@ -507,10 +723,56 @@ public void UpdateActivityWithInvalidConversationId() { try { ResourceResponse updateResponse = connector.getConversations().updateActivity("B21S8SG7K:T03CWQ0QB", response.getId(), activity); - Assert.fail("expected exception was not occurred."); - } catch (ErrorResponseException e) { - Assert.assertEquals("ServiceError", e.body().getError().getCode().toString()); - Assert.assertTrue(e.body().getError().getMessage().contains("Invalid ConversationId")); + Assert.fail("expected exception did not occur."); + } catch (CompletionException e) { + if (e.getCause() instanceof ErrorResponseException) { + Assert.assertEquals("ServiceError", ((ErrorResponseException)e.getCause()).body().getError().getCode()); + Assert.assertTrue(((ErrorResponseException)e.getCause()).body().getError().getMessage().contains("Invalid ConversationId")); + } else { + throw e; + } + } + } + + @Test + public void UpdateActivityWithNullConversationId() { + Activity activity = new Activity(ActivityTypes.MESSAGE) {{ + setRecipient(user); + setFrom(bot); + setText("TEST Activity to be updated with null conversation Id"); + }}; + + try { + connector.getConversations().updateActivity(null, "id", activity); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void UpdateActivityWithNullActivityId() { + Activity activity = new Activity(ActivityTypes.MESSAGE) {{ + setRecipient(user); + setFrom(bot); + setText("TEST Activity to be updated with null activity Id"); + }}; + + try { + connector.getConversations().updateActivity("id", null, activity); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); + } + } + + @Test + public void UpdateActivityWithNullActivity() { + try { + connector.getConversations().updateActivity("id", "id", null); + Assert.fail("expected exception did not occur."); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("cannot be null")); } } diff --git a/libraries/bot-connector/src/test/resources/session-records/CreateConversationWithNullParameter.json b/libraries/bot-connector/src/test/resources/session-records/CreateConversationWithNullParameter.json new file mode 100644 index 000000000..5c8f394b2 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/CreateConversationWithNullParameter.json @@ -0,0 +1,24 @@ +{ + "networkCallRecords": [ { + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21S8SG7J:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U8H8E2HSB:T03CWQ0QB\"\r\n }\r\n ],\r\n \"activity\": {\r\n \"type\": \"message\",\r\n \"from\": {\r\n \"id\": \"B21S8SG7J:T03CWQ0QB\"\r\n },\r\n \"recipient\": {\r\n \"id\": \"U8H8E2HSB:T03CWQ0QB\"\r\n },\r\n \"text\": \"TEST Create Conversation\"\r\n }\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "body": "{\r\n \"activityId\": \"1515187112.000022\",\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8PNY7UQ7\"\r\n}", + "content-type": "application/json; charset=utf-8", + "expires": "-1", + "cache-control": "no-cache", + "date": "Fri, 05 Jan 2018 21:18:31 GMT", + "pragma": "no-cache", + "server": "Microsoft-IIS/10.0", + "request-context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by": "ASP.NET", + "strict-transport-security": "max-age=31536000", + "StatusCode": 200 + } + }], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullActivityId.json b/libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullActivityId.json new file mode 100644 index 000000000..3876318a7 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullActivityId.json @@ -0,0 +1,48 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}],\"activity\":{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Delete Activity\"}}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:11 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"activityId\": \"1514572211.000260\",\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "DELETE", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities/1514572211.000260", + "Body" : "", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:12 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullConversationId.json b/libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullConversationId.json new file mode 100644 index 000000000..3876318a7 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/DeleteActivityWithNullConversationId.json @@ -0,0 +1,48 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}],\"activity\":{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Delete Activity\"}}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:11 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"activityId\": \"1514572211.000260\",\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "DELETE", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities/1514572211.000260", + "Body" : "", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:12 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullActivityId.json b/libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullActivityId.json new file mode 100644 index 000000000..2f54a4ec5 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullActivityId.json @@ -0,0 +1,25 @@ +{ + "networkCallRecords": [{ + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n }\r\n ],\r\n \"activity\": {\r\n \"type\": \"message\",\r\n \"from\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"recipient\": {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n },\r\n \"membersAdded\": [],\r\n \"membersRemoved\": [],\r\n \"reactionsAdded\": [],\r\n \"reactionsRemoved\": [],\r\n \"text\": \"TEST Get Activity Members with null conversation id\",\r\n \"attachments\": [],\r\n \"entities\": []\r\n }\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"activityId\": \"1516641070.000334\",\r\n \"id\": \"B21UTEF8S:T03CWQ0QB:D2369CT7C\"\r\n}", + "Content-Length": "83", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:10 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + }], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullConversationId.json b/libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullConversationId.json new file mode 100644 index 000000000..2f54a4ec5 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/GetActivityMembersWithNullConversationId.json @@ -0,0 +1,25 @@ +{ + "networkCallRecords": [{ + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n }\r\n ],\r\n \"activity\": {\r\n \"type\": \"message\",\r\n \"from\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"recipient\": {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n },\r\n \"membersAdded\": [],\r\n \"membersRemoved\": [],\r\n \"reactionsAdded\": [],\r\n \"reactionsRemoved\": [],\r\n \"text\": \"TEST Get Activity Members with null conversation id\",\r\n \"attachments\": [],\r\n \"entities\": []\r\n }\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"activityId\": \"1516641070.000334\",\r\n \"id\": \"B21UTEF8S:T03CWQ0QB:D2369CT7C\"\r\n}", + "Content-Length": "83", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:10 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + }], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/GetConversationMembersWithNullConversationId.json b/libraries/bot-connector/src/test/resources/session-records/GetConversationMembersWithNullConversationId.json new file mode 100644 index 000000000..7caaf7d8f --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/GetConversationMembersWithNullConversationId.json @@ -0,0 +1,25 @@ +{ + "networkCallRecords": [ { + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21S8SG7J:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U8H8E2HSB:T03CWQ0QB\"\r\n }\r\n ],\r\n \"activity\": {\r\n \"type\": \"message\",\r\n \"from\": {\r\n \"id\": \"B21S8SG7J:T03CWQ0QB\"\r\n },\r\n \"recipient\": {\r\n \"id\": \"U8H8E2HSB:T03CWQ0QB\"\r\n },\r\n \"text\": \"TEST Get Activity Members with null activity id\"\r\n }\r\n}", + "Headers": { + "User-Agent": "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"activityId\": \"1515595854.000017\",\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8PNY7UQ7\"\r\n}", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Cache-Control": "no-cache", + "Date": "Wed, 10 Jan 2018 14:50:54 GMT", + "Pragma": "no-cache", + "Server": "Microsoft-IIS/10.0", + "Set-Cookie": "ARRAffinity=cfaeda5806a3768888e707969568c07d2824ec67e3dd88e924400998c026e3ff;Path=/;HttpOnly;Domain=slack.botframework.com", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "X-Powered-By": "ASP.NET", + "Strict-Transport-Security": "max-age=31536000", + "StatusCode": 200 + } + }], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/GetConversationPagedMembersWithInvalidConversationId.json b/libraries/bot-connector/src/test/resources/session-records/GetConversationPagedMembersWithInvalidConversationId.json new file mode 100644 index 000000000..48aad8853 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/GetConversationPagedMembersWithInvalidConversationId.json @@ -0,0 +1,43 @@ +{ + "networkCallRecords": [ { + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n }\r\n ]\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"id\": \"B21UTEF8S:T03CWQ0QB:DD6UM0YHW\"\r\n}", + "Content-Length": "45", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Cache-Control": "no-cache", + "Pragma": "no-cache", + "Server": "Microsoft-IIS/10.0", + "Strict-Transport-Security": "max-age=31536000", + "Date": "Tue, 09 Oct 2018 18:35:49 GMT", + "StatusCode": 200 + } + }, + { + "Uri": "/v3/conversations/B21UTEF8S%3AT03CWQ0QB%3ADD6UM0YHWM/pagedmembers", + "Method": "GET", + "Body": "", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"error\": {\r\n \"code\": \"ServiceError\",\r\n \"message\": \"ExecuteWithActivityContext FAILED: The specified channel was not found\"\r\n }\r\n}", + "Content-Length": "141", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Cache-Control": "no-cache", + "Pragma": "no-cache", + "Server": "Microsoft-IIS/10.0", + "Strict-Transport-Security": "max-age=31536000", + "Date": "Tue, 09 Oct 2018 18:35:49 GMT", + "StatusCode": 400 + } + }], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivity.json b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivity.json new file mode 100644 index 000000000..d229789ac --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivity.json @@ -0,0 +1,49 @@ +{ + "networkCallRecords": [ + { + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n }\r\n ]\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"id\": \"B21UTEF8S:T03CWQ0QB:D2369CT7C\"\r\n}", + "Content-Length": "45", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:16 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + }, + { + "Uri": "/v3/conversations/B21UTEF8S:T03CWQ0QB:D2369CT7C/activities", + "Method": "POST", + "Body": "{\r\n \"type\": \"message\",\r\n \"from\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"recipient\": {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n },\r\n \"membersAdded\": [],\r\n \"membersRemoved\": [],\r\n \"reactionsAdded\": [],\r\n \"reactionsRemoved\": [],\r\n \"text\": \"TEST Reply activity with null conversation id\",\r\n \"attachments\": [],\r\n \"entities\": []\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"id\": \"1516641076.000646\"\r\n}", + "Content-Length": "33", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:16 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + } + ], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivityId.json b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivityId.json new file mode 100644 index 000000000..d229789ac --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullActivityId.json @@ -0,0 +1,49 @@ +{ + "networkCallRecords": [ + { + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n }\r\n ]\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"id\": \"B21UTEF8S:T03CWQ0QB:D2369CT7C\"\r\n}", + "Content-Length": "45", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:16 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + }, + { + "Uri": "/v3/conversations/B21UTEF8S:T03CWQ0QB:D2369CT7C/activities", + "Method": "POST", + "Body": "{\r\n \"type\": \"message\",\r\n \"from\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"recipient\": {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n },\r\n \"membersAdded\": [],\r\n \"membersRemoved\": [],\r\n \"reactionsAdded\": [],\r\n \"reactionsRemoved\": [],\r\n \"text\": \"TEST Reply activity with null conversation id\",\r\n \"attachments\": [],\r\n \"entities\": []\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"id\": \"1516641076.000646\"\r\n}", + "Content-Length": "33", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:16 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + } + ], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullConversationId.json b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullConversationId.json new file mode 100644 index 000000000..d229789ac --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullConversationId.json @@ -0,0 +1,49 @@ +{ + "networkCallRecords": [ + { + "Uri": "/v3/conversations", + "Method": "POST", + "Body": "{\r\n \"bot\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"members\": [\r\n {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n }\r\n ]\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"id\": \"B21UTEF8S:T03CWQ0QB:D2369CT7C\"\r\n}", + "Content-Length": "45", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:16 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + }, + { + "Uri": "/v3/conversations/B21UTEF8S:T03CWQ0QB:D2369CT7C/activities", + "Method": "POST", + "Body": "{\r\n \"type\": \"message\",\r\n \"from\": {\r\n \"id\": \"B21UTEF8S:T03CWQ0QB\"\r\n },\r\n \"recipient\": {\r\n \"id\": \"U19KH8EHJ:T03CWQ0QB\"\r\n },\r\n \"membersAdded\": [],\r\n \"membersRemoved\": [],\r\n \"reactionsAdded\": [],\r\n \"reactionsRemoved\": [],\r\n \"text\": \"TEST Reply activity with null conversation id\",\r\n \"attachments\": [],\r\n \"entities\": []\r\n}", + "Headers": { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "Body": "{\r\n \"id\": \"1516641076.000646\"\r\n}", + "Content-Length": "33", + "Content-Type": "application/json; charset=utf-8", + "Expires": "-1", + "Pragma": "no-cache", + "Request-Context": "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "Strict-Transport-Security": "max-age=31536000", + "Cache-Control": "no-cache", + "Date": "Mon, 22 Jan 2018 17:11:16 GMT", + "Server": "Microsoft-IIS/10.0", + "X-Powered-By": "ASP.NET", + "StatusCode": 200 + } + } + ], + "variables": [] +} diff --git a/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullReply.json b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullReply.json new file mode 100644 index 000000000..58bd3fc3b --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/ReplyToActivityWithNullReply.json @@ -0,0 +1,70 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}]}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:15 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities", + "Body" : "{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Send to Conversation\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:16 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572216.000048\"\r\n}" + } + }, { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities/1514572216.000048", + "Body" : "{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Reply to Activity\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:16 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572216.000202\"\r\n}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullActivity.json b/libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullActivity.json new file mode 100644 index 000000000..b5c37fdf6 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullActivity.json @@ -0,0 +1,48 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}]}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:39 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities", + "Body" : "{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Send to Conversation\",\"name\":\"activity\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:39 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572239.000123\"\r\n}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullConversationId.json b/libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullConversationId.json new file mode 100644 index 000000000..b5c37fdf6 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/SendToConversationWithNullConversationId.json @@ -0,0 +1,48 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}]}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:39 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities", + "Body" : "{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Send to Conversation\",\"name\":\"activity\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:30:39 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572239.000123\"\r\n}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivity.json b/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivity.json new file mode 100644 index 000000000..9c322cf33 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivity.json @@ -0,0 +1,70 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}]}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:32 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities", + "Body" : "{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Send to Conversation\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:32 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572172.000187\"\r\n}" + } + }, { + "Method" : "PUT", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities/1514572172.000187", + "Body" : "{\"type\":\"message\",\"id\":\"1514572172.000187\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Update Activity\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:33 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572172.000187\"\r\n}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivityId.json b/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivityId.json new file mode 100644 index 000000000..9c322cf33 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullActivityId.json @@ -0,0 +1,70 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}]}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:32 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities", + "Body" : "{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Send to Conversation\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:32 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572172.000187\"\r\n}" + } + }, { + "Method" : "PUT", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities/1514572172.000187", + "Body" : "{\"type\":\"message\",\"id\":\"1514572172.000187\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Update Activity\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:33 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572172.000187\"\r\n}" + } + } ], + "variables" : [ ] +} \ No newline at end of file diff --git a/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullConversationId.json b/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullConversationId.json new file mode 100644 index 000000000..9c322cf33 --- /dev/null +++ b/libraries/bot-connector/src/test/resources/session-records/UpdateActivityWithNullConversationId.json @@ -0,0 +1,70 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations", + "Body" : "{\"bot\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"members\":[{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"}]}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:32 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"B21S8SG7J:T03CWQ0QB:D8K7XGZU3\"\r\n}" + } + }, { + "Method" : "POST", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities", + "Body" : "{\"type\":\"message\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Send to Conversation\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:32 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572172.000187\"\r\n}" + } + }, { + "Method" : "PUT", + "Uri" : "https://slack.botframework.com/v3/conversations/B21S8SG7J:T03CWQ0QB:D8K7XGZU3/activities/1514572172.000187", + "Body" : "{\"type\":\"message\",\"id\":\"1514572172.000187\",\"from\":{\"id\":\"B21S8SG7J:T03CWQ0QB\"},\"recipient\":{\"id\":\"U3Z9ZUDK5:T03CWQ0QB\"},\"text\":\"TEST Update Activity\"}", + "Headers" : { + "User-Agent" : "Azure-SDK-For-Java/null OS:Windows 10/10.0 MacAddressHash:9e47c26c664df3d17fb33da29e81da7dc1985b292e3d49ee55b301a3f3f92046 Java:1.8.0_151 (BotConnector, 3.0)" + }, + "Response" : { + "date" : "Fri, 29 Dec 2017 18:29:33 GMT", + "server" : "Microsoft-IIS/10.0", + "expires" : "-1", + "vary" : "Accept-Encoding", + "retry-after" : "0", + "StatusCode" : "200", + "pragma" : "no-cache", + "strict-transport-security" : "max-age=31536000", + "request-context" : "appId=cid-v1:6814484e-c0d5-40ea-9dba-74ff29ca4f62", + "x-powered-by" : "ASP.NET", + "content-type" : "application/json; charset=utf-8", + "cache-control" : "no-cache", + "Body" : "{\r\n \"id\": \"1514572172.000187\"\r\n}" + } + } ], + "variables" : [ ] +} \ No newline at end of file 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 index b3cb4612f..ccccdfb5b 100644 --- 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 @@ -2,8 +2,8 @@ // Licensed under the MIT License. package com.microsoft.bot.sample.spring; + import com.microsoft.bot.connector.ConnectorClient; -import com.microsoft.bot.connector.ExecutorFactory; import com.microsoft.bot.connector.authentication.*; import com.microsoft.bot.schema.Activity; import org.slf4j.Logger; @@ -22,6 +22,7 @@ import com.microsoft.bot.connector.rest.RestConnectorClient; import com.microsoft.bot.schema.ActivityTypes; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; /** @@ -61,33 +62,37 @@ public void init() { * @return */ @PostMapping("/api/messages") - public ResponseEntity incoming(@RequestBody Activity activity, - @RequestHeader(value = "Authorization", defaultValue = "") String authHeader) { - try { - JwtTokenValidation.authenticateRequest(activity, authHeader, _credentialProvider, new SimpleChannelProvider()) - .thenRunAsync(() -> { - if (activity.getType().equals(ActivityTypes.MESSAGE)) { - logger.info("Received: " + activity.getText()); + public CompletableFuture> incoming(@RequestBody Activity activity, + @RequestHeader(value = "Authorization", defaultValue = "") String authHeader) { + return JwtTokenValidation.authenticateRequest(activity, authHeader, _credentialProvider, new SimpleChannelProvider()) + .thenAccept((identity) -> { + if (activity.getType().equals(ActivityTypes.MESSAGE)) { + logger.info("Received: " + activity.getText()); - // reply activity with the same text - ConnectorClient connector = new RestConnectorClient(activity.getServiceUrl(), _credentials); - connector.getConversations().sendToConversation( - activity.getConversation().getId(), - activity.createReply("Echo: " + activity.getText())); - } - }, ExecutorFactory.getExecutor()).join(); - } catch (CompletionException ex) { - if (ex.getCause() instanceof AuthenticationException) { - return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); - } - else { - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } - } catch (Exception ex) { - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } + // reply activity with the same text + ConnectorClient connector = new RestConnectorClient(activity.getServiceUrl(), _credentials); + connector.getConversations().sendToConversation( + activity.getConversation().getId(), + activity.createReply("Echo: " + activity.getText())); + } + }) + + .handle((identity, exception) -> { + if (exception == null) { + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } - // send ack to user activity - 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); + } + }); } }