Merge pull request #92 from microsoft/tb-packagenames
Changed package names.
This commit is contained in:
Коммит
699b607478
|
@ -2,19 +2,19 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.microsoft.bot.connector.sample</groupId>
|
||||
<artifactId>bot-connector-sample</artifactId>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>generator-botbuilder-java</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<parent>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-parent</artifactId>
|
||||
<version>4.0.0-a0</version>
|
||||
<relativePath>../../</relativePath>
|
||||
<version>4.0.0</version>
|
||||
<relativePath>../../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>bot-connector-sample</name>
|
||||
<name>generator-botbuilder-java</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
|
@ -86,4 +86,4 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
|
||||
# Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
# Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
|
@ -2,8 +2,8 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.microsoft.bot.builder</groupId>
|
||||
<artifactId>botbuilder</artifactId>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-builder</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>4.0-SNAPSHOT</version>
|
||||
|
||||
|
@ -107,12 +107,12 @@
|
|||
<version>0.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot.schema</groupId>
|
||||
<artifactId>botbuilder-schema</artifactId>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-schema</artifactId>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot.connector</groupId>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-connector</artifactId>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
@ -174,7 +174,7 @@
|
|||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<configuration>
|
||||
<outputDirectory>../../cobertura-report/botbuilder</outputDirectory>
|
||||
<outputDirectory>../../cobertura-report/bot-builder</outputDirectory>
|
||||
<format>xml</format>
|
||||
<maxmem>256m</maxmem>
|
||||
<!-- aggregated reports for multi-module projects -->
|
|
@ -1,37 +1,37 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Helper class for defining middleware by using a delegate or anonymous method.
|
||||
*/
|
||||
public class AnonymousReceiveMiddleware implements Middleware
|
||||
{
|
||||
private MiddlewareCall _toCall;
|
||||
|
||||
/**
|
||||
* Creates a middleware object that uses the provided method as its
|
||||
* process request handler.
|
||||
* @param anonymousMethod The method to use as the middleware's process
|
||||
* request handler.
|
||||
*/
|
||||
public AnonymousReceiveMiddleware(MiddlewareCall anonymousMethod)
|
||||
{
|
||||
if (anonymousMethod == null)
|
||||
throw new NullPointerException("MiddlewareCall anonymousMethod");
|
||||
else
|
||||
_toCall = anonymousMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the method provided in the {@link AnonymousReceiveMiddleware} to
|
||||
* process an incoming activity.
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
_toCall.requestHandler(context, next);
|
||||
}
|
||||
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Helper class for defining middleware by using a delegate or anonymous method.
|
||||
*/
|
||||
public class AnonymousReceiveMiddleware implements Middleware
|
||||
{
|
||||
private MiddlewareCall _toCall;
|
||||
|
||||
/**
|
||||
* Creates a middleware object that uses the provided method as its
|
||||
* process request handler.
|
||||
* @param anonymousMethod The method to use as the middleware's process
|
||||
* request handler.
|
||||
*/
|
||||
public AnonymousReceiveMiddleware(MiddlewareCall anonymousMethod)
|
||||
{
|
||||
if (anonymousMethod == null)
|
||||
throw new NullPointerException("MiddlewareCall anonymousMethod");
|
||||
else
|
||||
_toCall = anonymousMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the method provided in the {@link AnonymousReceiveMiddleware} to
|
||||
* process an incoming activity.
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
_toCall.requestHandler(context, next);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,176 +1,176 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
import com.microsoft.bot.schema.models.ConversationReferenceHelper;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents a bot adapter that can connect a bot to a service endpoint.
|
||||
* This class is abstract.
|
||||
* The bot adapter encapsulates authentication processes and sends
|
||||
* activities to and receives activities from the Bot Connector Service. When your
|
||||
* bot receives an activity, the adapter creates a context object, passes it to your
|
||||
* bot's application logic, and sends responses back to the user's channel.
|
||||
* <p>Use {@link Use(Middleware)} to add {@link Middleware} objects
|
||||
* to your adapter’s middleware collection. The adapter processes and directs
|
||||
* incoming activities in through the bot middleware pipeline to your bot’s logic
|
||||
* and then back out again. As each activity flows in and out of the bot, each piece
|
||||
* of middleware can inspect or act upon the activity, both before and after the bot
|
||||
* logic runs.</p>
|
||||
* <p>
|
||||
* {@linkalso TurnContext}
|
||||
* {@linkalso Activity}
|
||||
* {@linkalso Bot}
|
||||
* {@linkalso Middleware}
|
||||
*/
|
||||
public abstract class BotAdapter {
|
||||
/**
|
||||
* The collection of middleware in the adapter's pipeline.
|
||||
*/
|
||||
protected final MiddlewareSet _middlewareSet = new MiddlewareSet();
|
||||
|
||||
/**
|
||||
* Creates a default adapter.
|
||||
*/
|
||||
public BotAdapter() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds middleware to the adapter's pipeline.
|
||||
*
|
||||
* @param middleware The middleware to add.
|
||||
* @return The updated adapter object.
|
||||
* Middleware is added to the adapter at initialization time.
|
||||
* For each turn, the adapter calls middleware in the order in which you added it.
|
||||
*/
|
||||
public BotAdapter Use(Middleware middleware) {
|
||||
_middlewareSet.Use(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, sends activities to the conversation.
|
||||
*
|
||||
* @param context The context object for the turn.
|
||||
* @param activities The activities to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activities are successfully sent, the task result contains
|
||||
* an array of {@link ResourceResponse} objects containing the IDs that
|
||||
* the receiving channel assigned to the activities.
|
||||
* {@linkalso TurnContext.OnSendActivities(SendActivitiesHandler)}
|
||||
*/
|
||||
public abstract ResourceResponse[] SendActivities(TurnContext context, Activity[] activities) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, replaces an existing activity in the
|
||||
* conversation.
|
||||
*
|
||||
* @param context The context object for the turn.
|
||||
* @param activity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>Before calling this, set the ID of the replacement activity to the ID
|
||||
* of the activity to replace.</p>
|
||||
* {@linkalso TurnContext.OnUpdateActivity(UpdateActivityHandler)}
|
||||
*/
|
||||
public abstract ResourceResponse UpdateActivity(TurnContext context, Activity activity);
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, deletes an existing activity in the
|
||||
* conversation.
|
||||
*
|
||||
* @param context The context object for the turn.
|
||||
* @param reference Conversation reference for the activity to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* The {@link ConversationReference.ActivityId} of the conversation
|
||||
* reference identifies the activity to delete.
|
||||
* {@linkalso TurnContext.OnDeleteActivity(DeleteActivityHandler)}
|
||||
*/
|
||||
public abstract void DeleteActivity(TurnContext context, ConversationReference reference) throws ExecutionException, InterruptedException;
|
||||
|
||||
|
||||
/**
|
||||
* Starts activity processing for the current bot turn.
|
||||
*
|
||||
* @param context The turn's context object.
|
||||
* @param callback A callback method to run at the end of the pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* @throws NullPointerException {@code context} is null.
|
||||
* The adapter calls middleware in the order in which you added it.
|
||||
* The adapter passes in the context object for the turn and a next delegate,
|
||||
* and the middleware calls the delegate to pass control to the next middleware
|
||||
* in the pipeline. Once control reaches the end of the pipeline, the adapter calls
|
||||
* the {@code callback} method. If a middleware component doesn’t call
|
||||
* the next delegate, the adapter does not call any of the subsequent middleware’s
|
||||
* {@link Middleware.OnTurn(TurnContext, MiddlewareSet.NextDelegate)}
|
||||
* methods or the callback method, and the pipeline short circuits.
|
||||
* <p>When the turn is initiated by a user activity (reactive messaging), the
|
||||
* callback method will be a reference to the bot's
|
||||
* {@link Bot.OnTurn(TurnContext)} method. When the turn is
|
||||
* initiated by a call to {@link ContinueConversation(ConversationReference, Func{TurnContext, Task})}
|
||||
* (proactive messaging), the callback method is the callback method that was provided in the call.</p>
|
||||
*/
|
||||
protected void RunPipeline(TurnContext context, Consumer<TurnContext> callback) throws Exception {
|
||||
BotAssert.ContextNotNull(context);
|
||||
|
||||
// Call any registered Middleware Components looking for ReceiveActivity()
|
||||
if (context.getActivity() != null) {
|
||||
_middlewareSet.ReceiveActivityWithStatus(context, callback);
|
||||
} else {
|
||||
// call back to caller on proactive case
|
||||
if (callback != null) {
|
||||
callback.accept(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a conversation on the specified channel.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @param callback A method to call when the new conversation is available.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* @throws UnsupportedOperationException No base implementation is provided.
|
||||
*/
|
||||
public CompletableFuture CreateConversation(String channelId, Function<TurnContext, CompletableFuture> callback) {
|
||||
throw new UnsupportedOperationException("Adapter does not support CreateConversation with this arguments");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a proactive message to a conversation.
|
||||
*
|
||||
* @param botId The application ID of the bot. This paramter is ignored in
|
||||
* single tenant the Adpters (Console, Test, etc) but is critical to the BotFrameworkAdapter
|
||||
* which is multi-tenant aware.
|
||||
* @param reference A reference to the conversation to continue.
|
||||
* @param callback The method to call for the resulting bot turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* Call this method to proactively send a message to a conversation.
|
||||
* Most channels require a user to initaiate a conversation with a bot
|
||||
* before the bot can send activities to the user.
|
||||
* {@linkalso RunPipeline(TurnContext, Func { TurnContext, Task })}
|
||||
*/
|
||||
public void ContinueConversation(String botId, ConversationReference reference, Consumer<TurnContext> callback) throws Exception {
|
||||
|
||||
ConversationReferenceHelper conv = new ConversationReferenceHelper(reference);
|
||||
ActivityImpl activity = conv.GetPostToBotMessage();
|
||||
|
||||
try (TurnContextImpl context = new TurnContextImpl(this, activity)) {
|
||||
this.RunPipeline(context, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
import com.microsoft.bot.schema.models.ConversationReferenceHelper;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents a bot adapter that can connect a bot to a service endpoint.
|
||||
* This class is abstract.
|
||||
* The bot adapter encapsulates authentication processes and sends
|
||||
* activities to and receives activities from the Bot Connector Service. When your
|
||||
* bot receives an activity, the adapter creates a context object, passes it to your
|
||||
* bot's application logic, and sends responses back to the user's channel.
|
||||
* <p>Use {@link Use(Middleware)} to add {@link Middleware} objects
|
||||
* to your adapter’s middleware collection. The adapter processes and directs
|
||||
* incoming activities in through the bot middleware pipeline to your bot’s logic
|
||||
* and then back out again. As each activity flows in and out of the bot, each piece
|
||||
* of middleware can inspect or act upon the activity, both before and after the bot
|
||||
* logic runs.</p>
|
||||
* <p>
|
||||
* {@linkalso TurnContext}
|
||||
* {@linkalso Activity}
|
||||
* {@linkalso Bot}
|
||||
* {@linkalso Middleware}
|
||||
*/
|
||||
public abstract class BotAdapter {
|
||||
/**
|
||||
* The collection of middleware in the adapter's pipeline.
|
||||
*/
|
||||
protected final MiddlewareSet _middlewareSet = new MiddlewareSet();
|
||||
|
||||
/**
|
||||
* Creates a default adapter.
|
||||
*/
|
||||
public BotAdapter() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds middleware to the adapter's pipeline.
|
||||
*
|
||||
* @param middleware The middleware to add.
|
||||
* @return The updated adapter object.
|
||||
* Middleware is added to the adapter at initialization time.
|
||||
* For each turn, the adapter calls middleware in the order in which you added it.
|
||||
*/
|
||||
public BotAdapter Use(Middleware middleware) {
|
||||
_middlewareSet.Use(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, sends activities to the conversation.
|
||||
*
|
||||
* @param context The context object for the turn.
|
||||
* @param activities The activities to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activities are successfully sent, the task result contains
|
||||
* an array of {@link ResourceResponse} objects containing the IDs that
|
||||
* the receiving channel assigned to the activities.
|
||||
* {@linkalso TurnContext.OnSendActivities(SendActivitiesHandler)}
|
||||
*/
|
||||
public abstract ResourceResponse[] SendActivities(TurnContext context, Activity[] activities) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, replaces an existing activity in the
|
||||
* conversation.
|
||||
*
|
||||
* @param context The context object for the turn.
|
||||
* @param activity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>Before calling this, set the ID of the replacement activity to the ID
|
||||
* of the activity to replace.</p>
|
||||
* {@linkalso TurnContext.OnUpdateActivity(UpdateActivityHandler)}
|
||||
*/
|
||||
public abstract ResourceResponse UpdateActivity(TurnContext context, Activity activity);
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, deletes an existing activity in the
|
||||
* conversation.
|
||||
*
|
||||
* @param context The context object for the turn.
|
||||
* @param reference Conversation reference for the activity to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* The {@link ConversationReference.ActivityId} of the conversation
|
||||
* reference identifies the activity to delete.
|
||||
* {@linkalso TurnContext.OnDeleteActivity(DeleteActivityHandler)}
|
||||
*/
|
||||
public abstract void DeleteActivity(TurnContext context, ConversationReference reference) throws ExecutionException, InterruptedException;
|
||||
|
||||
|
||||
/**
|
||||
* Starts activity processing for the current bot turn.
|
||||
*
|
||||
* @param context The turn's context object.
|
||||
* @param callback A callback method to run at the end of the pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* @throws NullPointerException {@code context} is null.
|
||||
* The adapter calls middleware in the order in which you added it.
|
||||
* The adapter passes in the context object for the turn and a next delegate,
|
||||
* and the middleware calls the delegate to pass control to the next middleware
|
||||
* in the pipeline. Once control reaches the end of the pipeline, the adapter calls
|
||||
* the {@code callback} method. If a middleware component doesn’t call
|
||||
* the next delegate, the adapter does not call any of the subsequent middleware’s
|
||||
* {@link Middleware.OnTurn(TurnContext, MiddlewareSet.NextDelegate)}
|
||||
* methods or the callback method, and the pipeline short circuits.
|
||||
* <p>When the turn is initiated by a user activity (reactive messaging), the
|
||||
* callback method will be a reference to the bot's
|
||||
* {@link Bot.OnTurn(TurnContext)} method. When the turn is
|
||||
* initiated by a call to {@link ContinueConversation(ConversationReference, Func{TurnContext, Task})}
|
||||
* (proactive messaging), the callback method is the callback method that was provided in the call.</p>
|
||||
*/
|
||||
protected void RunPipeline(TurnContext context, Consumer<TurnContext> callback) throws Exception {
|
||||
BotAssert.ContextNotNull(context);
|
||||
|
||||
// Call any registered Middleware Components looking for ReceiveActivity()
|
||||
if (context.getActivity() != null) {
|
||||
_middlewareSet.ReceiveActivityWithStatus(context, callback);
|
||||
} else {
|
||||
// call back to caller on proactive case
|
||||
if (callback != null) {
|
||||
callback.accept(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a conversation on the specified channel.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @param callback A method to call when the new conversation is available.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* @throws UnsupportedOperationException No base implementation is provided.
|
||||
*/
|
||||
public CompletableFuture CreateConversation(String channelId, Function<TurnContext, CompletableFuture> callback) {
|
||||
throw new UnsupportedOperationException("Adapter does not support CreateConversation with this arguments");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a proactive message to a conversation.
|
||||
*
|
||||
* @param botId The application ID of the bot. This paramter is ignored in
|
||||
* single tenant the Adpters (Console, Test, etc) but is critical to the BotFrameworkAdapter
|
||||
* which is multi-tenant aware.
|
||||
* @param reference A reference to the conversation to continue.
|
||||
* @param callback The method to call for the resulting bot turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* Call this method to proactively send a message to a conversation.
|
||||
* Most channels require a user to initaiate a conversation with a bot
|
||||
* before the bot can send activities to the user.
|
||||
* {@linkalso RunPipeline(TurnContext, Func { TurnContext, Task })}
|
||||
*/
|
||||
public void ContinueConversation(String botId, ConversationReference reference, Consumer<TurnContext> callback) throws Exception {
|
||||
|
||||
ConversationReferenceHelper conv = new ConversationReferenceHelper(reference);
|
||||
ActivityImpl activity = conv.GetPostToBotMessage();
|
||||
|
||||
try (TurnContextImpl context = new TurnContextImpl(this, activity)) {
|
||||
this.RunPipeline(context, callback);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,99 +1,99 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Provides methods for debugging Bot Builder code.
|
||||
*/
|
||||
public class BotAssert
|
||||
{
|
||||
/**
|
||||
* Checks that an activity object is not {@code null}.
|
||||
* @param activity The activity object.
|
||||
* @throws NullPointerException
|
||||
* {@code activity} is {@code null}.
|
||||
*/
|
||||
public static void ActivityNotNull(ActivityImpl activity)
|
||||
{
|
||||
if (activity == null)
|
||||
throw new IllegalArgumentException ("Activity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that an activity object is not {@code null}.
|
||||
* @param activity The activity object.
|
||||
* @throws NullPointerException
|
||||
* {@code activity} is {@code null}.
|
||||
*/
|
||||
public static void ActivityNotNull(Activity activity)
|
||||
{
|
||||
if (activity == null)
|
||||
throw new IllegalArgumentException ("Activity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a context object is not {@code null}.
|
||||
* @param context The context object.
|
||||
* @throws NullPointerException
|
||||
* {@code context} is {@code null}.
|
||||
*/
|
||||
public static void ContextNotNull(TurnContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException ("TurnContext");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a conversation reference object is not {@code null}.
|
||||
* @param reference The conversation reference object.
|
||||
* @throws NullPointerException
|
||||
* {@code reference} is {@code null}.
|
||||
*/
|
||||
public static void ConversationReferenceNotNull(ConversationReference reference)
|
||||
{
|
||||
if (reference == null)
|
||||
throw new IllegalArgumentException ("ConversationReference");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that an activity collection is not {@code null}.
|
||||
* @param activities The activities.
|
||||
* @throws NullPointerException
|
||||
* {@code activities} is {@code null}.
|
||||
*/
|
||||
public static void ActivityListNotNull(ArrayList<Activity> activities)
|
||||
{
|
||||
if (activities == null)
|
||||
throw new NullPointerException("List<Activity>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a middleware object is not {@code null}.
|
||||
* @param middleware The middleware object.
|
||||
* @throws NullPointerException
|
||||
* {@code middleware} is {@code null}.
|
||||
*/
|
||||
public static void MiddlewareNotNull(Middleware middleware)
|
||||
{
|
||||
if (middleware == null)
|
||||
throw new NullPointerException("Middleware");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a middleware collection is not {@code null}.
|
||||
* @param middleware The middleware.
|
||||
* @throws NullPointerException
|
||||
* {@code middleware} is {@code null}.
|
||||
*/
|
||||
public static void MiddlewareNotNull(ArrayList<Middleware> middleware)
|
||||
{
|
||||
if (middleware == null)
|
||||
throw new NullPointerException("List<Middleware>");
|
||||
}
|
||||
}
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Provides methods for debugging Bot Builder code.
|
||||
*/
|
||||
public class BotAssert
|
||||
{
|
||||
/**
|
||||
* Checks that an activity object is not {@code null}.
|
||||
* @param activity The activity object.
|
||||
* @throws NullPointerException
|
||||
* {@code activity} is {@code null}.
|
||||
*/
|
||||
public static void ActivityNotNull(ActivityImpl activity)
|
||||
{
|
||||
if (activity == null)
|
||||
throw new IllegalArgumentException ("Activity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that an activity object is not {@code null}.
|
||||
* @param activity The activity object.
|
||||
* @throws NullPointerException
|
||||
* {@code activity} is {@code null}.
|
||||
*/
|
||||
public static void ActivityNotNull(Activity activity)
|
||||
{
|
||||
if (activity == null)
|
||||
throw new IllegalArgumentException ("Activity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a context object is not {@code null}.
|
||||
* @param context The context object.
|
||||
* @throws NullPointerException
|
||||
* {@code context} is {@code null}.
|
||||
*/
|
||||
public static void ContextNotNull(TurnContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException ("TurnContext");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a conversation reference object is not {@code null}.
|
||||
* @param reference The conversation reference object.
|
||||
* @throws NullPointerException
|
||||
* {@code reference} is {@code null}.
|
||||
*/
|
||||
public static void ConversationReferenceNotNull(ConversationReference reference)
|
||||
{
|
||||
if (reference == null)
|
||||
throw new IllegalArgumentException ("ConversationReference");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that an activity collection is not {@code null}.
|
||||
* @param activities The activities.
|
||||
* @throws NullPointerException
|
||||
* {@code activities} is {@code null}.
|
||||
*/
|
||||
public static void ActivityListNotNull(ArrayList<Activity> activities)
|
||||
{
|
||||
if (activities == null)
|
||||
throw new NullPointerException("List<Activity>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a middleware object is not {@code null}.
|
||||
* @param middleware The middleware object.
|
||||
* @throws NullPointerException
|
||||
* {@code middleware} is {@code null}.
|
||||
*/
|
||||
public static void MiddlewareNotNull(Middleware middleware)
|
||||
{
|
||||
if (middleware == null)
|
||||
throw new NullPointerException("Middleware");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a middleware collection is not {@code null}.
|
||||
* @param middleware The middleware.
|
||||
* @throws NullPointerException
|
||||
* {@code middleware} is {@code null}.
|
||||
*/
|
||||
public static void MiddlewareNotNull(ArrayList<Middleware> middleware)
|
||||
{
|
||||
if (middleware == null)
|
||||
throw new NullPointerException("List<Middleware>");
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,165 +1,165 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
|
||||
/**
|
||||
* Abstract Base class which manages details of automatic loading and saving of bot state.
|
||||
*
|
||||
* @param TState The type of the bot state object.
|
||||
*/
|
||||
//public class BotState<TState> : Middleware
|
||||
// where TState : class, new()
|
||||
public class BotState<TState> implements Middleware {
|
||||
|
||||
private final StateSettings settings;
|
||||
private final Storage storage;
|
||||
private final Function<TurnContext, String> keyDelegate;
|
||||
private final String propertyName;
|
||||
private final Supplier<? extends TState> ctor;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BotState{TState}} middleware object.
|
||||
*
|
||||
* @param name The name to use to load or save the state object.
|
||||
* @param storage The storage provider to use.
|
||||
* @param settings The state persistance options to use.
|
||||
*/
|
||||
public BotState(Storage storage, String propertyName, Function<TurnContext, String> keyDelegate, Supplier<? extends TState> ctor) {
|
||||
this(storage, propertyName, keyDelegate, ctor, null);
|
||||
}
|
||||
|
||||
public BotState(Storage storage, String propertyName, Function<TurnContext, String> keyDelegate, Supplier<? extends TState> ctor, StateSettings settings) {
|
||||
if (null == storage) {
|
||||
throw new IllegalArgumentException("Storage");
|
||||
}
|
||||
if (null == propertyName) {
|
||||
throw new IllegalArgumentException("String propertyName");
|
||||
}
|
||||
if (null == keyDelegate) {
|
||||
throw new IllegalArgumentException("Key Delegate");
|
||||
}
|
||||
if (null == ctor) {
|
||||
throw new IllegalArgumentException("ctor");
|
||||
}
|
||||
this.ctor = ctor;
|
||||
this.storage = storage;
|
||||
this.propertyName = propertyName;
|
||||
this.keyDelegate = keyDelegate;
|
||||
if (null == settings)
|
||||
this.settings = new StateSettings();
|
||||
else
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processess an incoming activity.
|
||||
*
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* This middleware loads the state object on the leading edge of the middleware pipeline
|
||||
* and persists the state object on the trailing edge.
|
||||
*/
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
ReadToContextService(context);
|
||||
next.next();
|
||||
WriteFromContextService(context).join();
|
||||
return;
|
||||
}
|
||||
|
||||
protected void ReadToContextService(TurnContext context) throws IllegalArgumentException, JsonProcessingException {
|
||||
String key = this.keyDelegate.apply(context);
|
||||
Map<String, ?> items = null;
|
||||
try {
|
||||
CompletableFuture<Map<String, ?>> result = storage.Read(new String[]{key});
|
||||
items = result.get();
|
||||
System.out.println(String.format("BotState:OnTurn(tid:%s) ReadToContextService: Found %s items", Thread.currentThread().getId(), items.size()));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Error waiting context storage read: %s", e.toString()));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
TState state = StreamSupport.stream(items.entrySet().spliterator(), false)
|
||||
.filter(entry -> entry.getKey() == key)
|
||||
.map(Map.Entry::getValue)
|
||||
.map(entry -> (TState) entry)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
|
||||
//var state = items.Where(entry => entry.Key == key).Select(entry => entry.Value).OfType<TState>().FirstOrDefault();
|
||||
if (state == null)
|
||||
state = ctor.get();
|
||||
context.getServices().Add(this.propertyName, state);
|
||||
}
|
||||
|
||||
protected CompletableFuture WriteFromContextService(TurnContext context) throws Exception {
|
||||
TState state = context.getServices().Get(this.propertyName);
|
||||
return Write(context, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads state from storage.
|
||||
*
|
||||
* @param TState The type of the bot state object.
|
||||
* @param context The context object for this turn.
|
||||
*/
|
||||
public CompletableFuture<TState> Read(TurnContext context) throws JsonProcessingException {
|
||||
String key = this.keyDelegate.apply(context);
|
||||
Map<String, ?> items = storage.Read(new String[]{key}).join();
|
||||
TState state = StreamSupport.stream(items.entrySet().spliterator(), false)
|
||||
.filter(item -> item.getKey() == key)
|
||||
.map(Map.Entry::getValue)
|
||||
.map(item -> (TState) item)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//var state = items.Where(entry => entry.Key == key).Select(entry => entry.Value).OfType<TState>().FirstOrDefault();
|
||||
if (state == null)
|
||||
state = ctor.get();
|
||||
return completedFuture(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes state to storage.
|
||||
*
|
||||
* @param context The context object for this turn.
|
||||
* @param state The state object.
|
||||
*/
|
||||
public CompletableFuture Write(TurnContext context, TState state) throws Exception {
|
||||
HashMap<String, TState> changes = new HashMap<String, TState>();
|
||||
//List<Map.Entry<String, ?>> changes = new ArrayList<Map.Entry<String, ?>>();
|
||||
if (state == null)
|
||||
state = ctor.get();
|
||||
String key = keyDelegate.apply(context);
|
||||
changes.put(key, state);
|
||||
|
||||
if (this.settings.getLastWriterWins()) {
|
||||
for (Map.Entry<String, ?> item : changes.entrySet()) {
|
||||
if (item.getValue() instanceof StoreItem) {
|
||||
StoreItem valueStoreItem = (StoreItem) item.getValue();
|
||||
valueStoreItem.seteTag("*");
|
||||
}
|
||||
}
|
||||
}
|
||||
return completedFuture(storage.Write(changes).join());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
|
||||
/**
|
||||
* Abstract Base class which manages details of automatic loading and saving of bot state.
|
||||
*
|
||||
* @param TState The type of the bot state object.
|
||||
*/
|
||||
//public class BotState<TState> : Middleware
|
||||
// where TState : class, new()
|
||||
public class BotState<TState> implements Middleware {
|
||||
|
||||
private final StateSettings settings;
|
||||
private final Storage storage;
|
||||
private final Function<TurnContext, String> keyDelegate;
|
||||
private final String propertyName;
|
||||
private final Supplier<? extends TState> ctor;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BotState{TState}} middleware object.
|
||||
*
|
||||
* @param name The name to use to load or save the state object.
|
||||
* @param storage The storage provider to use.
|
||||
* @param settings The state persistance options to use.
|
||||
*/
|
||||
public BotState(Storage storage, String propertyName, Function<TurnContext, String> keyDelegate, Supplier<? extends TState> ctor) {
|
||||
this(storage, propertyName, keyDelegate, ctor, null);
|
||||
}
|
||||
|
||||
public BotState(Storage storage, String propertyName, Function<TurnContext, String> keyDelegate, Supplier<? extends TState> ctor, StateSettings settings) {
|
||||
if (null == storage) {
|
||||
throw new IllegalArgumentException("Storage");
|
||||
}
|
||||
if (null == propertyName) {
|
||||
throw new IllegalArgumentException("String propertyName");
|
||||
}
|
||||
if (null == keyDelegate) {
|
||||
throw new IllegalArgumentException("Key Delegate");
|
||||
}
|
||||
if (null == ctor) {
|
||||
throw new IllegalArgumentException("ctor");
|
||||
}
|
||||
this.ctor = ctor;
|
||||
this.storage = storage;
|
||||
this.propertyName = propertyName;
|
||||
this.keyDelegate = keyDelegate;
|
||||
if (null == settings)
|
||||
this.settings = new StateSettings();
|
||||
else
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processess an incoming activity.
|
||||
*
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* This middleware loads the state object on the leading edge of the middleware pipeline
|
||||
* and persists the state object on the trailing edge.
|
||||
*/
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
ReadToContextService(context);
|
||||
next.next();
|
||||
WriteFromContextService(context).join();
|
||||
return;
|
||||
}
|
||||
|
||||
protected void ReadToContextService(TurnContext context) throws IllegalArgumentException, JsonProcessingException {
|
||||
String key = this.keyDelegate.apply(context);
|
||||
Map<String, ?> items = null;
|
||||
try {
|
||||
CompletableFuture<Map<String, ?>> result = storage.Read(new String[]{key});
|
||||
items = result.get();
|
||||
System.out.println(String.format("BotState:OnTurn(tid:%s) ReadToContextService: Found %s items", Thread.currentThread().getId(), items.size()));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Error waiting context storage read: %s", e.toString()));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
TState state = StreamSupport.stream(items.entrySet().spliterator(), false)
|
||||
.filter(entry -> entry.getKey() == key)
|
||||
.map(Map.Entry::getValue)
|
||||
.map(entry -> (TState) entry)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
|
||||
//var state = items.Where(entry => entry.Key == key).Select(entry => entry.Value).OfType<TState>().FirstOrDefault();
|
||||
if (state == null)
|
||||
state = ctor.get();
|
||||
context.getServices().Add(this.propertyName, state);
|
||||
}
|
||||
|
||||
protected CompletableFuture WriteFromContextService(TurnContext context) throws Exception {
|
||||
TState state = context.getServices().Get(this.propertyName);
|
||||
return Write(context, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads state from storage.
|
||||
*
|
||||
* @param TState The type of the bot state object.
|
||||
* @param context The context object for this turn.
|
||||
*/
|
||||
public CompletableFuture<TState> Read(TurnContext context) throws JsonProcessingException {
|
||||
String key = this.keyDelegate.apply(context);
|
||||
Map<String, ?> items = storage.Read(new String[]{key}).join();
|
||||
TState state = StreamSupport.stream(items.entrySet().spliterator(), false)
|
||||
.filter(item -> item.getKey() == key)
|
||||
.map(Map.Entry::getValue)
|
||||
.map(item -> (TState) item)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//var state = items.Where(entry => entry.Key == key).Select(entry => entry.Value).OfType<TState>().FirstOrDefault();
|
||||
if (state == null)
|
||||
state = ctor.get();
|
||||
return completedFuture(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes state to storage.
|
||||
*
|
||||
* @param context The context object for this turn.
|
||||
* @param state The state object.
|
||||
*/
|
||||
public CompletableFuture Write(TurnContext context, TState state) throws Exception {
|
||||
HashMap<String, TState> changes = new HashMap<String, TState>();
|
||||
//List<Map.Entry<String, ?>> changes = new ArrayList<Map.Entry<String, ?>>();
|
||||
if (state == null)
|
||||
state = ctor.get();
|
||||
String key = keyDelegate.apply(context);
|
||||
changes.put(key, state);
|
||||
|
||||
if (this.settings.getLastWriterWins()) {
|
||||
for (Map.Entry<String, ?> item : changes.entrySet()) {
|
||||
if (item.getValue() instanceof StoreItem) {
|
||||
StoreItem valueStoreItem = (StoreItem) item.getValue();
|
||||
valueStoreItem.seteTag("*");
|
||||
}
|
||||
}
|
||||
}
|
||||
return completedFuture(storage.Write(changes).join());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface CallOnException {
|
||||
<T> CompletableFuture apply(TurnContext context, T t ) throws Exception;
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface CallOnException {
|
||||
<T> CompletableFuture apply(TurnContext context, T t ) throws Exception;
|
||||
}
|
|
@ -1,46 +1,46 @@
|
|||
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* This piece of middleware can be added to allow you to handle exceptions when they are thrown
|
||||
* within your bot's code or middleware further down the pipeline. Using this handler you might
|
||||
* send an appropriate message to the user to let them know that something has gone wrong.
|
||||
* You can specify the type of exception the middleware should catch and this middleware can be added
|
||||
* multiple times to allow you to handle different exception types in different ways.
|
||||
*
|
||||
* @param T The type of the exception that you want to catch. This can be 'Exception' to
|
||||
* catch all or a specific type of exception
|
||||
*/
|
||||
public class CatchExceptionMiddleware<T extends Exception> implements Middleware {
|
||||
private final CallOnException _handler;
|
||||
private final Class<T> _exceptionType;
|
||||
|
||||
public CatchExceptionMiddleware(CallOnException callOnException, Class<T> exceptionType) {
|
||||
_handler = callOnException;
|
||||
_exceptionType = exceptionType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
|
||||
Class c = _exceptionType.getDeclaringClass();
|
||||
|
||||
try {
|
||||
// Continue to route the activity through the pipeline
|
||||
// any errors further down the pipeline will be caught by
|
||||
// this try / catch
|
||||
next.next();
|
||||
} catch (Exception ex) {
|
||||
|
||||
if (_exceptionType.isInstance(ex))
|
||||
// If an error is thrown and the exception is of type T then invoke the handler
|
||||
_handler.<T>apply(context, (T) ex);
|
||||
else
|
||||
throw ex;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* This piece of middleware can be added to allow you to handle exceptions when they are thrown
|
||||
* within your bot's code or middleware further down the pipeline. Using this handler you might
|
||||
* send an appropriate message to the user to let them know that something has gone wrong.
|
||||
* You can specify the type of exception the middleware should catch and this middleware can be added
|
||||
* multiple times to allow you to handle different exception types in different ways.
|
||||
*
|
||||
* @param T The type of the exception that you want to catch. This can be 'Exception' to
|
||||
* catch all or a specific type of exception
|
||||
*/
|
||||
public class CatchExceptionMiddleware<T extends Exception> implements Middleware {
|
||||
private final CallOnException _handler;
|
||||
private final Class<T> _exceptionType;
|
||||
|
||||
public CatchExceptionMiddleware(CallOnException callOnException, Class<T> exceptionType) {
|
||||
_handler = callOnException;
|
||||
_exceptionType = exceptionType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
|
||||
Class c = _exceptionType.getDeclaringClass();
|
||||
|
||||
try {
|
||||
// Continue to route the activity through the pipeline
|
||||
// any errors further down the pipeline will be caught by
|
||||
// this try / catch
|
||||
next.next();
|
||||
} catch (Exception ex) {
|
||||
|
||||
if (_exceptionType.isInstance(ex))
|
||||
// If an error is thrown and the exception is of type T then invoke the handler
|
||||
_handler.<T>apply(context, (T) ex);
|
||||
else
|
||||
throw ex;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +1,49 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Handles persistence of a conversation state object using the conversation ID as part of the key.
|
||||
* @param TState The type of the conversation state object.
|
||||
*/
|
||||
public class ConversationState<TState> extends BotState<TState>
|
||||
{
|
||||
/**
|
||||
* The key to use to read and write this conversation state object to storage.
|
||||
*/
|
||||
//
|
||||
// Note: Hard coded to maintain compatibility with C#
|
||||
// "ConversationState:{typeof(ConversationState<TState>).Namespace}.{typeof(ConversationState<TState>).Name}"
|
||||
public static String PropertyName() {
|
||||
return String.format("ConversationState:Microsoft.Bot.Builder.Core.Extensions.ConversationState`1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConversationState{TState}} object.
|
||||
* @param storage The storage provider to use.
|
||||
* @param settings The state persistance options to use.
|
||||
*/
|
||||
public ConversationState(Storage storage, Supplier<? extends TState> ctor) {
|
||||
this(storage, null, ctor);
|
||||
}
|
||||
|
||||
public ConversationState(Storage storage, StateSettings settings, Supplier<? extends TState> ctor) {
|
||||
super(storage, PropertyName(),
|
||||
(context) -> {
|
||||
return String.format("conversation/%s/%s", context.getActivity().channelId(), context.getActivity().conversation().id());
|
||||
},
|
||||
ctor,
|
||||
settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conversation state object from turn context.
|
||||
* @param context The context object for this turn.
|
||||
* @return The coversation state object.
|
||||
*/
|
||||
public static <TState> TState Get(TurnContext context) throws IllegalArgumentException {
|
||||
return context.getServices().Get(PropertyName());
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Handles persistence of a conversation state object using the conversation ID as part of the key.
|
||||
* @param TState The type of the conversation state object.
|
||||
*/
|
||||
public class ConversationState<TState> extends BotState<TState>
|
||||
{
|
||||
/**
|
||||
* The key to use to read and write this conversation state object to storage.
|
||||
*/
|
||||
//
|
||||
// Note: Hard coded to maintain compatibility with C#
|
||||
// "ConversationState:{typeof(ConversationState<TState>).Namespace}.{typeof(ConversationState<TState>).Name}"
|
||||
public static String PropertyName() {
|
||||
return String.format("ConversationState:Microsoft.Bot.Builder.Core.Extensions.ConversationState`1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConversationState{TState}} object.
|
||||
* @param storage The storage provider to use.
|
||||
* @param settings The state persistance options to use.
|
||||
*/
|
||||
public ConversationState(Storage storage, Supplier<? extends TState> ctor) {
|
||||
this(storage, null, ctor);
|
||||
}
|
||||
|
||||
public ConversationState(Storage storage, StateSettings settings, Supplier<? extends TState> ctor) {
|
||||
super(storage, PropertyName(),
|
||||
(context) -> {
|
||||
return String.format("conversation/%s/%s", context.getActivity().channelId(), context.getActivity().conversation().id());
|
||||
},
|
||||
ctor,
|
||||
settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conversation state object from turn context.
|
||||
* @param context The context object for this turn.
|
||||
* @return The coversation state object.
|
||||
*/
|
||||
public static <TState> TState Get(TurnContext context) throws IllegalArgumentException {
|
||||
return context.getServices().Get(PropertyName());
|
||||
}
|
||||
}
|
|
@ -1,25 +1,25 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
/**
|
||||
* A method that can participate in delete activity events for the current turn.
|
||||
* @param context The context object for the turn.
|
||||
* @param reference The conversation containing the activity.
|
||||
* @param next The delegate to call to continue event processing.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* A handler calls the {@code next} delegate to pass control to
|
||||
* the next registered handler. If a handler doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent handlers and does not delete the
|
||||
*activity.
|
||||
* <p>The conversation reference's {@link ConversationReference.ActivityId}
|
||||
* indicates the activity in the conversation to replace.</p>
|
||||
*
|
||||
* {@linkalso BotAdapter}
|
||||
* {@linkalso SendActivitiesHandler}
|
||||
* {@linkalso UpdateActivityHandler}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DeleteActivityHandler {
|
||||
void handle(TurnContext context, ConversationReference reference, Runnable next) throws Exception;
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
/**
|
||||
* A method that can participate in delete activity events for the current turn.
|
||||
* @param context The context object for the turn.
|
||||
* @param reference The conversation containing the activity.
|
||||
* @param next The delegate to call to continue event processing.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* A handler calls the {@code next} delegate to pass control to
|
||||
* the next registered handler. If a handler doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent handlers and does not delete the
|
||||
*activity.
|
||||
* <p>The conversation reference's {@link ConversationReference.ActivityId}
|
||||
* indicates the activity in the conversation to replace.</p>
|
||||
*
|
||||
* {@linkalso BotAdapter}
|
||||
* {@linkalso SendActivitiesHandler}
|
||||
* {@linkalso UpdateActivityHandler}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DeleteActivityHandler {
|
||||
void handle(TurnContext context, ConversationReference reference, Runnable next) throws Exception;
|
||||
}
|
|
@ -1,37 +1,37 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* Tuple class containing an HTTP Status Code and a JSON Serializable
|
||||
* object. The HTTP Status code is, in the invoke activity scenario, what will
|
||||
* be set in the resulting POST. The Body of the resulting POST will be
|
||||
* the JSON Serialized content from the Body property.
|
||||
*/
|
||||
public class InvokeResponse {
|
||||
/**
|
||||
* The POST that is generated in response to the incoming Invoke Activity
|
||||
* will have the HTTP Status code specificied by this field.
|
||||
*/
|
||||
private int _status;
|
||||
|
||||
public int getStatus() {
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this._status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* The POST that is generated in response to the incoming Invoke Activity
|
||||
* will have a body generated by JSON serializing the object in the Body field.
|
||||
*/
|
||||
private Object _body;
|
||||
|
||||
public Object getBody() {
|
||||
return _body;
|
||||
}
|
||||
|
||||
public void setBody(Object body) {
|
||||
this._body = body;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* Tuple class containing an HTTP Status Code and a JSON Serializable
|
||||
* object. The HTTP Status code is, in the invoke activity scenario, what will
|
||||
* be set in the resulting POST. The Body of the resulting POST will be
|
||||
* the JSON Serialized content from the Body property.
|
||||
*/
|
||||
public class InvokeResponse {
|
||||
/**
|
||||
* The POST that is generated in response to the incoming Invoke Activity
|
||||
* will have the HTTP Status code specificied by this field.
|
||||
*/
|
||||
private int _status;
|
||||
|
||||
public int getStatus() {
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this._status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* The POST that is generated in response to the incoming Invoke Activity
|
||||
* will have a body generated by JSON serializing the object in the Body field.
|
||||
*/
|
||||
private Object _body;
|
||||
|
||||
public Object getBody() {
|
||||
return _body;
|
||||
}
|
||||
|
||||
public void setBody(Object body) {
|
||||
this._body = body;
|
||||
}
|
||||
}
|
|
@ -1,310 +1,310 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* The memory transcript store stores transcripts in volatile memory in a Dictionary.
|
||||
* <p>
|
||||
* <p>
|
||||
* Because this uses an unbounded volitile dictionary this should only be used for unit tests or non-production environments.
|
||||
*/
|
||||
public class MemoryTranscriptStore implements TranscriptStore {
|
||||
private HashMap<String, HashMap<String, ArrayList<Activity>>> channels = new HashMap<String, HashMap<String, ArrayList<Activity>>>();
|
||||
final ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory() {
|
||||
@Override
|
||||
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName("TestFlow-" + worker.getPoolIndex());
|
||||
return worker;
|
||||
}
|
||||
};
|
||||
|
||||
final ExecutorService executor = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, false);
|
||||
|
||||
|
||||
/**
|
||||
* Logs an activity to the transcript.
|
||||
*
|
||||
* @param activity The activity to log.
|
||||
* @return A CompletableFuture that represents the work queued to execute.
|
||||
*/
|
||||
public final void LogActivityAsync(Activity activity) {
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null for LogActivity()");
|
||||
}
|
||||
|
||||
synchronized (this.channels) {
|
||||
HashMap<String, ArrayList<Activity>> channel;
|
||||
if (!this.channels.containsKey(activity.channelId())) {
|
||||
channel = new HashMap<String, ArrayList<Activity>>();
|
||||
this.channels.put(activity.channelId(), channel);
|
||||
} else {
|
||||
channel = this.channels.get(activity.channelId());
|
||||
}
|
||||
|
||||
ArrayList<Activity> transcript = null;
|
||||
|
||||
|
||||
if (!channel.containsKey(activity.conversation().id())) {
|
||||
transcript = new ArrayList<Activity>();
|
||||
channel.put(activity.conversation().id(), transcript);
|
||||
} else {
|
||||
transcript = channel.get(activity.conversation().id());
|
||||
}
|
||||
|
||||
transcript.add(activity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken) {
|
||||
return GetTranscriptActivitiesAsync(channelId, conversationId, continuationToken, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId) {
|
||||
return GetTranscriptActivitiesAsync(channelId, conversationId, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @param startDate A cutoff date. Activities older than this date are not included.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
public final CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken, DateTime startDate) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (channelId == null) {
|
||||
throw new NullPointerException(String.format("missing %1$s", "channelId"));
|
||||
}
|
||||
|
||||
if (conversationId == null) {
|
||||
throw new NullPointerException(String.format("missing %1$s", "conversationId"));
|
||||
}
|
||||
|
||||
PagedResult<Activity> pagedResult = new PagedResult<Activity>();
|
||||
synchronized (channels) {
|
||||
HashMap<String, ArrayList<Activity>> channel;
|
||||
if (!channels.containsKey(channelId)) {
|
||||
return pagedResult;
|
||||
}
|
||||
channel = channels.get(channelId);
|
||||
ArrayList<Activity> transcript;
|
||||
|
||||
if (!channel.containsKey(conversationId)) {
|
||||
return pagedResult;
|
||||
}
|
||||
transcript = channel.get(conversationId);
|
||||
if (continuationToken != null) {
|
||||
List<Activity> items = transcript.stream()
|
||||
.sorted(Comparator.comparing(Activity::timestamp))
|
||||
.filter(a -> a.timestamp().compareTo(startDate) >= 0)
|
||||
.filter(skipwhile(a -> !a.id().equals(continuationToken)))
|
||||
.skip(1)
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
pagedResult.items(items.toArray(new Activity[items.size()]));
|
||||
|
||||
if (pagedResult.getItems().length == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).id());
|
||||
}
|
||||
} else {
|
||||
List<Activity> items = transcript.stream()
|
||||
.sorted(Comparator.comparing(Activity::timestamp))
|
||||
.filter(a -> a.timestamp().compareTo((startDate == null) ? new DateTime(Long.MIN_VALUE) : startDate) >= 0)
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
pagedResult.items(items.toArray(new Activity[items.size()]));
|
||||
if (items.size() == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pagedResult;
|
||||
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes conversation data from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public final CompletableFuture DeleteTranscriptAsync(String channelId, String conversationId) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
if (channelId == null) {
|
||||
throw new NullPointerException(String.format("%1$s should not be null", "channelId"));
|
||||
}
|
||||
|
||||
if (conversationId == null) {
|
||||
throw new NullPointerException(String.format("%1$s should not be null", "conversationId"));
|
||||
}
|
||||
|
||||
synchronized (this.channels) {
|
||||
if (!this.channels.containsKey(channelId)) {
|
||||
return;
|
||||
}
|
||||
HashMap<String, ArrayList<Activity>> channel = this.channels.get(channelId);
|
||||
if (channel.containsKey(conversationId)) {
|
||||
channel.remove(conversationId);
|
||||
}
|
||||
}
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conversations on a channel from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId) {
|
||||
return ListTranscriptsAsync(channelId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conversations on a channel from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @param continuationToken
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId, String continuationToken) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (channelId == null) {
|
||||
throw new NullPointerException(String.format("missing %1$s", "channelId"));
|
||||
}
|
||||
|
||||
PagedResult<Transcript> pagedResult = new PagedResult<Transcript>();
|
||||
synchronized (channels) {
|
||||
|
||||
if (!channels.containsKey(channelId)) {
|
||||
return pagedResult;
|
||||
}
|
||||
|
||||
HashMap<String, ArrayList<Activity>> channel = channels.get(channelId);
|
||||
if (continuationToken != null) {
|
||||
List<Transcript> items = channel.entrySet().stream()
|
||||
.map(c -> {
|
||||
OffsetDateTime offsetDateTime = null;
|
||||
if (c.getValue().stream().findFirst().isPresent()) {
|
||||
DateTime dt = c.getValue().stream().findFirst().get().timestamp();
|
||||
// convert to DateTime to OffsetDateTime
|
||||
Instant instant = Instant.ofEpochMilli(dt.getMillis());
|
||||
ZoneOffset offset = ZoneId.of(dt.getZone().getID()).getRules().getOffset(instant);
|
||||
offsetDateTime = instant.atOffset(offset);
|
||||
} else {
|
||||
offsetDateTime = OffsetDateTime.now();
|
||||
}
|
||||
return new Transcript()
|
||||
.withChannelId(channelId)
|
||||
.withId(c.getKey())
|
||||
.withCreated(offsetDateTime);
|
||||
}
|
||||
)
|
||||
.sorted(Comparator.comparing(Transcript::getCreated))
|
||||
.filter(skipwhile(c -> !c.getId().equals(continuationToken)))
|
||||
.skip(1)
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
pagedResult.items(items.toArray(new Transcript[items.size()]));
|
||||
if (items.size() == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).getId());
|
||||
}
|
||||
} else {
|
||||
|
||||
List<Transcript> items = channel.entrySet().stream()
|
||||
.map(c -> {
|
||||
OffsetDateTime offsetDateTime = null;
|
||||
if (c.getValue().stream().findFirst().isPresent()) {
|
||||
DateTime dt = c.getValue().stream().findFirst().get().timestamp();
|
||||
// convert to DateTime to OffsetDateTime
|
||||
Instant instant = Instant.ofEpochMilli(dt.getMillis());
|
||||
ZoneOffset offset = ZoneId.of(dt.getZone().getID()).getRules().getOffset(instant);
|
||||
offsetDateTime = instant.atOffset(offset);
|
||||
} else {
|
||||
offsetDateTime = OffsetDateTime.now();
|
||||
}
|
||||
return new Transcript()
|
||||
.withChannelId(channelId)
|
||||
.withId(c.getKey())
|
||||
.withCreated(offsetDateTime);
|
||||
}
|
||||
)
|
||||
.sorted(Comparator.comparing(Transcript::getCreated))
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
pagedResult.items(items.toArray(new Transcript[items.size()]));
|
||||
if (items.size() == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return pagedResult;
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emulate C# SkipWhile.
|
||||
* Stateful
|
||||
*
|
||||
* @param func1 predicate to apply
|
||||
* @param <T> type
|
||||
* @return if the predicate condition is true
|
||||
*/
|
||||
public static <T> Predicate<T> skipwhile(Function<? super T, Object> func1) {
|
||||
final boolean[] started = {false};
|
||||
return t -> started[0] || (started[0] = (boolean) func1.apply(t));
|
||||
}
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* The memory transcript store stores transcripts in volatile memory in a Dictionary.
|
||||
* <p>
|
||||
* <p>
|
||||
* Because this uses an unbounded volitile dictionary this should only be used for unit tests or non-production environments.
|
||||
*/
|
||||
public class MemoryTranscriptStore implements TranscriptStore {
|
||||
private HashMap<String, HashMap<String, ArrayList<Activity>>> channels = new HashMap<String, HashMap<String, ArrayList<Activity>>>();
|
||||
final ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory() {
|
||||
@Override
|
||||
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName("TestFlow-" + worker.getPoolIndex());
|
||||
return worker;
|
||||
}
|
||||
};
|
||||
|
||||
final ExecutorService executor = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, false);
|
||||
|
||||
|
||||
/**
|
||||
* Logs an activity to the transcript.
|
||||
*
|
||||
* @param activity The activity to log.
|
||||
* @return A CompletableFuture that represents the work queued to execute.
|
||||
*/
|
||||
public final void LogActivityAsync(Activity activity) {
|
||||
if (activity == null) {
|
||||
throw new NullPointerException("activity cannot be null for LogActivity()");
|
||||
}
|
||||
|
||||
synchronized (this.channels) {
|
||||
HashMap<String, ArrayList<Activity>> channel;
|
||||
if (!this.channels.containsKey(activity.channelId())) {
|
||||
channel = new HashMap<String, ArrayList<Activity>>();
|
||||
this.channels.put(activity.channelId(), channel);
|
||||
} else {
|
||||
channel = this.channels.get(activity.channelId());
|
||||
}
|
||||
|
||||
ArrayList<Activity> transcript = null;
|
||||
|
||||
|
||||
if (!channel.containsKey(activity.conversation().id())) {
|
||||
transcript = new ArrayList<Activity>();
|
||||
channel.put(activity.conversation().id(), transcript);
|
||||
} else {
|
||||
transcript = channel.get(activity.conversation().id());
|
||||
}
|
||||
|
||||
transcript.add(activity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken) {
|
||||
return GetTranscriptActivitiesAsync(channelId, conversationId, continuationToken, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId) {
|
||||
return GetTranscriptActivitiesAsync(channelId, conversationId, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @param startDate A cutoff date. Activities older than this date are not included.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
public final CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken, DateTime startDate) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (channelId == null) {
|
||||
throw new NullPointerException(String.format("missing %1$s", "channelId"));
|
||||
}
|
||||
|
||||
if (conversationId == null) {
|
||||
throw new NullPointerException(String.format("missing %1$s", "conversationId"));
|
||||
}
|
||||
|
||||
PagedResult<Activity> pagedResult = new PagedResult<Activity>();
|
||||
synchronized (channels) {
|
||||
HashMap<String, ArrayList<Activity>> channel;
|
||||
if (!channels.containsKey(channelId)) {
|
||||
return pagedResult;
|
||||
}
|
||||
channel = channels.get(channelId);
|
||||
ArrayList<Activity> transcript;
|
||||
|
||||
if (!channel.containsKey(conversationId)) {
|
||||
return pagedResult;
|
||||
}
|
||||
transcript = channel.get(conversationId);
|
||||
if (continuationToken != null) {
|
||||
List<Activity> items = transcript.stream()
|
||||
.sorted(Comparator.comparing(Activity::timestamp))
|
||||
.filter(a -> a.timestamp().compareTo(startDate) >= 0)
|
||||
.filter(skipwhile(a -> !a.id().equals(continuationToken)))
|
||||
.skip(1)
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
pagedResult.items(items.toArray(new Activity[items.size()]));
|
||||
|
||||
if (pagedResult.getItems().length == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).id());
|
||||
}
|
||||
} else {
|
||||
List<Activity> items = transcript.stream()
|
||||
.sorted(Comparator.comparing(Activity::timestamp))
|
||||
.filter(a -> a.timestamp().compareTo((startDate == null) ? new DateTime(Long.MIN_VALUE) : startDate) >= 0)
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
pagedResult.items(items.toArray(new Activity[items.size()]));
|
||||
if (items.size() == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pagedResult;
|
||||
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes conversation data from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public final CompletableFuture DeleteTranscriptAsync(String channelId, String conversationId) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
if (channelId == null) {
|
||||
throw new NullPointerException(String.format("%1$s should not be null", "channelId"));
|
||||
}
|
||||
|
||||
if (conversationId == null) {
|
||||
throw new NullPointerException(String.format("%1$s should not be null", "conversationId"));
|
||||
}
|
||||
|
||||
synchronized (this.channels) {
|
||||
if (!this.channels.containsKey(channelId)) {
|
||||
return;
|
||||
}
|
||||
HashMap<String, ArrayList<Activity>> channel = this.channels.get(channelId);
|
||||
if (channel.containsKey(conversationId)) {
|
||||
channel.remove(conversationId);
|
||||
}
|
||||
}
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conversations on a channel from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId) {
|
||||
return ListTranscriptsAsync(channelId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the conversations on a channel from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @param continuationToken
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
||||
public final CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId, String continuationToken) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (channelId == null) {
|
||||
throw new NullPointerException(String.format("missing %1$s", "channelId"));
|
||||
}
|
||||
|
||||
PagedResult<Transcript> pagedResult = new PagedResult<Transcript>();
|
||||
synchronized (channels) {
|
||||
|
||||
if (!channels.containsKey(channelId)) {
|
||||
return pagedResult;
|
||||
}
|
||||
|
||||
HashMap<String, ArrayList<Activity>> channel = channels.get(channelId);
|
||||
if (continuationToken != null) {
|
||||
List<Transcript> items = channel.entrySet().stream()
|
||||
.map(c -> {
|
||||
OffsetDateTime offsetDateTime = null;
|
||||
if (c.getValue().stream().findFirst().isPresent()) {
|
||||
DateTime dt = c.getValue().stream().findFirst().get().timestamp();
|
||||
// convert to DateTime to OffsetDateTime
|
||||
Instant instant = Instant.ofEpochMilli(dt.getMillis());
|
||||
ZoneOffset offset = ZoneId.of(dt.getZone().getID()).getRules().getOffset(instant);
|
||||
offsetDateTime = instant.atOffset(offset);
|
||||
} else {
|
||||
offsetDateTime = OffsetDateTime.now();
|
||||
}
|
||||
return new Transcript()
|
||||
.withChannelId(channelId)
|
||||
.withId(c.getKey())
|
||||
.withCreated(offsetDateTime);
|
||||
}
|
||||
)
|
||||
.sorted(Comparator.comparing(Transcript::getCreated))
|
||||
.filter(skipwhile(c -> !c.getId().equals(continuationToken)))
|
||||
.skip(1)
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
pagedResult.items(items.toArray(new Transcript[items.size()]));
|
||||
if (items.size() == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).getId());
|
||||
}
|
||||
} else {
|
||||
|
||||
List<Transcript> items = channel.entrySet().stream()
|
||||
.map(c -> {
|
||||
OffsetDateTime offsetDateTime = null;
|
||||
if (c.getValue().stream().findFirst().isPresent()) {
|
||||
DateTime dt = c.getValue().stream().findFirst().get().timestamp();
|
||||
// convert to DateTime to OffsetDateTime
|
||||
Instant instant = Instant.ofEpochMilli(dt.getMillis());
|
||||
ZoneOffset offset = ZoneId.of(dt.getZone().getID()).getRules().getOffset(instant);
|
||||
offsetDateTime = instant.atOffset(offset);
|
||||
} else {
|
||||
offsetDateTime = OffsetDateTime.now();
|
||||
}
|
||||
return new Transcript()
|
||||
.withChannelId(channelId)
|
||||
.withId(c.getKey())
|
||||
.withCreated(offsetDateTime);
|
||||
}
|
||||
)
|
||||
.sorted(Comparator.comparing(Transcript::getCreated))
|
||||
.limit(20)
|
||||
.collect(Collectors.toList());
|
||||
pagedResult.items(items.toArray(new Transcript[items.size()]));
|
||||
if (items.size() == 20) {
|
||||
pagedResult.withContinuationToken(items.get(items.size() - 1).getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return pagedResult;
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emulate C# SkipWhile.
|
||||
* Stateful
|
||||
*
|
||||
* @param func1 predicate to apply
|
||||
* @param <T> type
|
||||
* @return if the predicate condition is true
|
||||
*/
|
||||
public static <T> Predicate<T> skipwhile(Function<? super T, Object> func1) {
|
||||
final boolean[] started = {false};
|
||||
return t -> started[0] || (started[0] = (boolean) func1.apply(t));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +1,57 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* Represents middleware that can operate on incoming activities.
|
||||
* A {@link BotAdapter} passes incoming activities from the user's
|
||||
* channel to the middleware's {@link OnTurn(TurnContext, NextDelegate)}
|
||||
* method.
|
||||
* <p>You can add middleware objects to your adapter’s middleware collection. The
|
||||
* adapter processes and directs incoming activities in through the bot middleware
|
||||
* pipeline to your bot’s logic and then back out again. As each activity flows in
|
||||
* and out of the bot, each piece of middleware can inspect or act upon the activity,
|
||||
* both before and after the bot logic runs.</p>
|
||||
* <p>For each activity, the adapter calls middleware in the order in which you
|
||||
* added it.</p>
|
||||
*
|
||||
* <example>
|
||||
* This defines middleware that sends "before" and "after" messages
|
||||
* before and after the adapter calls the bot's
|
||||
* {@link Bot.OnTurn(TurnContext)} method.
|
||||
* <code>
|
||||
* public class SampleMiddleware : Middleware
|
||||
* {
|
||||
* public async Task OnTurn(TurnContext context, MiddlewareSet.NextDelegate next)
|
||||
* {
|
||||
* context.SendActivity("before");
|
||||
* await next().ConfigureAwait(false);
|
||||
* context.SendActivity("after");
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
* </example>
|
||||
* {@linkalso Bot}
|
||||
*/
|
||||
public interface Middleware
|
||||
{
|
||||
/**
|
||||
* Processess an incoming activity.
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* Middleware calls the {@code next} delegate to pass control to
|
||||
* the next middleware in the pipeline. If middleware doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent middleware’s request handlers or the
|
||||
* bot’s receive handler, and the pipeline short circuits.
|
||||
* <p>The {@code context} provides information about the
|
||||
* incoming activity, and other data needed to process the activity.</p>
|
||||
*
|
||||
* {@linkalso TurnContext}
|
||||
* {@linkalso Bot.Schema.Activity}
|
||||
*/
|
||||
void OnTurn(TurnContext context, NextDelegate next) throws Exception;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* Represents middleware that can operate on incoming activities.
|
||||
* A {@link BotAdapter} passes incoming activities from the user's
|
||||
* channel to the middleware's {@link OnTurn(TurnContext, NextDelegate)}
|
||||
* method.
|
||||
* <p>You can add middleware objects to your adapter’s middleware collection. The
|
||||
* adapter processes and directs incoming activities in through the bot middleware
|
||||
* pipeline to your bot’s logic and then back out again. As each activity flows in
|
||||
* and out of the bot, each piece of middleware can inspect or act upon the activity,
|
||||
* both before and after the bot logic runs.</p>
|
||||
* <p>For each activity, the adapter calls middleware in the order in which you
|
||||
* added it.</p>
|
||||
*
|
||||
* <example>
|
||||
* This defines middleware that sends "before" and "after" messages
|
||||
* before and after the adapter calls the bot's
|
||||
* {@link Bot.OnTurn(TurnContext)} method.
|
||||
* <code>
|
||||
* public class SampleMiddleware : Middleware
|
||||
* {
|
||||
* public async Task OnTurn(TurnContext context, MiddlewareSet.NextDelegate next)
|
||||
* {
|
||||
* context.SendActivity("before");
|
||||
* await next().ConfigureAwait(false);
|
||||
* context.SendActivity("after");
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
* </example>
|
||||
* {@linkalso Bot}
|
||||
*/
|
||||
public interface Middleware
|
||||
{
|
||||
/**
|
||||
* Processess an incoming activity.
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* Middleware calls the {@code next} delegate to pass control to
|
||||
* the next middleware in the pipeline. If middleware doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent middleware’s request handlers or the
|
||||
* bot’s receive handler, and the pipeline short circuits.
|
||||
* <p>The {@code context} provides information about the
|
||||
* incoming activity, and other data needed to process the activity.</p>
|
||||
*
|
||||
* {@linkalso TurnContext}
|
||||
* {@linkalso Bot.Schema.Activity}
|
||||
*/
|
||||
void OnTurn(TurnContext context, NextDelegate next) throws Exception;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MiddlewareCall {
|
||||
void requestHandler(TurnContext tc, NextDelegate nd) throws Exception;
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MiddlewareCall {
|
||||
void requestHandler(TurnContext tc, NextDelegate nd) throws Exception;
|
||||
}
|
|
@ -1,97 +1,97 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MiddlewareSet implements Middleware {
|
||||
public NextDelegate Next;
|
||||
|
||||
private final ArrayList<Middleware> _middleware = new ArrayList<Middleware>();
|
||||
|
||||
public MiddlewareSet Use(Middleware middleware) {
|
||||
BotAssert.MiddlewareNotNull(middleware);
|
||||
_middleware.add(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ReceiveActivity(TurnContextImpl context)
|
||||
throws Exception {
|
||||
ReceiveActivityInternal(context, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
ReceiveActivityInternal((TurnContextImpl) context, null);
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("MiddlewareSet::OnTurn next delegate: %s", e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnTurn(TurnContextImpl context, CompletableFuture next)
|
||||
throws ExecutionException, InterruptedException {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended to be called from Bot, this method performs exactly the same as the
|
||||
* standard ReceiveActivity, except that it runs a user-defined delegate returns
|
||||
* if all Middleware in the receive pipeline was run.
|
||||
*/
|
||||
public void ReceiveActivityWithStatus(TurnContext context, Consumer<TurnContext> callback)
|
||||
throws Exception {
|
||||
ReceiveActivityInternal(context, callback);
|
||||
}
|
||||
|
||||
private void ReceiveActivityInternal(TurnContext context, Consumer<TurnContext> callback)
|
||||
throws Exception {
|
||||
ReceiveActivityInternal(context, callback, 0);
|
||||
}
|
||||
|
||||
private void ReceiveActivityInternal(TurnContext context, Consumer<TurnContext> callback, int nextMiddlewareIndex)
|
||||
throws Exception {
|
||||
// Check if we're at the end of the middleware list yet
|
||||
if (nextMiddlewareIndex == _middleware.size()) {
|
||||
// If all the Middlware ran, the "leading edge" of the tree is now complete.
|
||||
// This means it's time to run any developer specified callback.
|
||||
// Once this callback is done, the "trailing edge" calls are then completed. This
|
||||
// allows code that looks like:
|
||||
// Trace.TraceInformation("before");
|
||||
// await next();
|
||||
// Trace.TraceInformation("after");
|
||||
// to run as expected.
|
||||
|
||||
// If a callback was provided invoke it now and return its task, otherwise just return the completed task
|
||||
if (callback == null) {
|
||||
return ;
|
||||
} else {
|
||||
callback.accept(context);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next piece of middleware
|
||||
Middleware nextMiddleware = _middleware.get(nextMiddlewareIndex);
|
||||
NextDelegate next = new NextDelegate() {
|
||||
public void next() throws Exception {
|
||||
ReceiveActivityInternal(context, callback, nextMiddlewareIndex + 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Execute the next middleware passing a closure that will recurse back into this method at the next piece of middlware as the NextDelegate
|
||||
nextMiddleware.OnTurn(
|
||||
context,
|
||||
next);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MiddlewareSet implements Middleware {
|
||||
public NextDelegate Next;
|
||||
|
||||
private final ArrayList<Middleware> _middleware = new ArrayList<Middleware>();
|
||||
|
||||
public MiddlewareSet Use(Middleware middleware) {
|
||||
BotAssert.MiddlewareNotNull(middleware);
|
||||
_middleware.add(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ReceiveActivity(TurnContextImpl context)
|
||||
throws Exception {
|
||||
ReceiveActivityInternal(context, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
ReceiveActivityInternal((TurnContextImpl) context, null);
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("MiddlewareSet::OnTurn next delegate: %s", e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnTurn(TurnContextImpl context, CompletableFuture next)
|
||||
throws ExecutionException, InterruptedException {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended to be called from Bot, this method performs exactly the same as the
|
||||
* standard ReceiveActivity, except that it runs a user-defined delegate returns
|
||||
* if all Middleware in the receive pipeline was run.
|
||||
*/
|
||||
public void ReceiveActivityWithStatus(TurnContext context, Consumer<TurnContext> callback)
|
||||
throws Exception {
|
||||
ReceiveActivityInternal(context, callback);
|
||||
}
|
||||
|
||||
private void ReceiveActivityInternal(TurnContext context, Consumer<TurnContext> callback)
|
||||
throws Exception {
|
||||
ReceiveActivityInternal(context, callback, 0);
|
||||
}
|
||||
|
||||
private void ReceiveActivityInternal(TurnContext context, Consumer<TurnContext> callback, int nextMiddlewareIndex)
|
||||
throws Exception {
|
||||
// Check if we're at the end of the middleware list yet
|
||||
if (nextMiddlewareIndex == _middleware.size()) {
|
||||
// If all the Middlware ran, the "leading edge" of the tree is now complete.
|
||||
// This means it's time to run any developer specified callback.
|
||||
// Once this callback is done, the "trailing edge" calls are then completed. This
|
||||
// allows code that looks like:
|
||||
// Trace.TraceInformation("before");
|
||||
// await next();
|
||||
// Trace.TraceInformation("after");
|
||||
// to run as expected.
|
||||
|
||||
// If a callback was provided invoke it now and return its task, otherwise just return the completed task
|
||||
if (callback == null) {
|
||||
return ;
|
||||
} else {
|
||||
callback.accept(context);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next piece of middleware
|
||||
Middleware nextMiddleware = _middleware.get(nextMiddlewareIndex);
|
||||
NextDelegate next = new NextDelegate() {
|
||||
public void next() throws Exception {
|
||||
ReceiveActivityInternal(context, callback, nextMiddlewareIndex + 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Execute the next middleware passing a closure that will recurse back into this method at the next piece of middlware as the NextDelegate
|
||||
nextMiddleware.OnTurn(
|
||||
context,
|
||||
next);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface NextDelegate {
|
||||
void next() throws Exception;
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface NextDelegate {
|
||||
void next() throws Exception;
|
||||
}
|
|
@ -1,43 +1,43 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
/**
|
||||
Page of results from an enumeration.
|
||||
|
||||
<typeparam name="T"></typeparam>
|
||||
*/
|
||||
public class PagedResult<T>
|
||||
{
|
||||
/**
|
||||
Page of items.
|
||||
*/
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow direct instantiation of arrays of generic type parameters:
|
||||
//ORIGINAL LINE: private T[] Items = new T[0];
|
||||
private T[] items = (T[])new Object[0];
|
||||
public final T[] getItems()
|
||||
{
|
||||
return this.items;
|
||||
}
|
||||
public final void items(T[] value)
|
||||
{
|
||||
this.items = value;
|
||||
}
|
||||
|
||||
/**
|
||||
Token used to page through multiple pages.
|
||||
*/
|
||||
private String continuationToken;
|
||||
public final String continuationToken()
|
||||
{
|
||||
return this.continuationToken;
|
||||
}
|
||||
public final PagedResult<T> withContinuationToken(String value)
|
||||
{
|
||||
this.continuationToken = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
/**
|
||||
Page of results from an enumeration.
|
||||
|
||||
<typeparam name="T"></typeparam>
|
||||
*/
|
||||
public class PagedResult<T>
|
||||
{
|
||||
/**
|
||||
Page of items.
|
||||
*/
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow direct instantiation of arrays of generic type parameters:
|
||||
//ORIGINAL LINE: private T[] Items = new T[0];
|
||||
private T[] items = (T[])new Object[0];
|
||||
public final T[] getItems()
|
||||
{
|
||||
return this.items;
|
||||
}
|
||||
public final void items(T[] value)
|
||||
{
|
||||
this.items = value;
|
||||
}
|
||||
|
||||
/**
|
||||
Token used to page through multiple pages.
|
||||
*/
|
||||
private String continuationToken;
|
||||
public final String continuationToken()
|
||||
{
|
||||
return this.continuationToken;
|
||||
}
|
||||
public final PagedResult<T> withContinuationToken(String value)
|
||||
{
|
||||
this.continuationToken = value;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SendActivitiesHandler {
|
||||
ResourceResponse[] handle(TurnContext context, List<Activity> activities, Callable<ResourceResponse[]> next) throws Exception;
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SendActivitiesHandler {
|
||||
ResourceResponse[] handle(TurnContext context, List<Activity> activities, Callable<ResourceResponse[]> next) throws Exception;
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class StateSettings
|
||||
{
|
||||
private boolean lastWriterWins = true;
|
||||
public boolean getLastWriterWins() {
|
||||
return this.lastWriterWins;
|
||||
}
|
||||
public void setLast(boolean lastWriterWins) {
|
||||
this.lastWriterWins = lastWriterWins;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class StateSettings
|
||||
{
|
||||
private boolean lastWriterWins = true;
|
||||
public boolean getLastWriterWins() {
|
||||
return this.lastWriterWins;
|
||||
}
|
||||
public void setLast(boolean lastWriterWins) {
|
||||
this.lastWriterWins = lastWriterWins;
|
||||
}
|
||||
}
|
|
@ -1,32 +1,32 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.ConversationState;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.builder.UserState;
|
||||
|
||||
/**
|
||||
* Provides helper methods for getting state objects from the turn context.
|
||||
*/
|
||||
public class StateTurnContextExtensions
|
||||
{
|
||||
/**
|
||||
* Gets a conversation state object from the turn context.
|
||||
* @param TState The type of the state object to get.
|
||||
* @param context The context object for this turn.
|
||||
* @return The state object.
|
||||
*/
|
||||
public static <TState extends Object> TState GetConversationState(TurnContext context) throws IllegalArgumentException {
|
||||
|
||||
return ConversationState.<TState>Get(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a user state object from the turn context.
|
||||
* @param TState The type of the state object to get.
|
||||
* @param context The context object for this turn.
|
||||
* @return The state object.
|
||||
*/
|
||||
public static <TState> TState GetUserState(TurnContext context) throws IllegalArgumentException {
|
||||
return UserState.<TState>Get(context);
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.ConversationState;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.builder.UserState;
|
||||
|
||||
/**
|
||||
* Provides helper methods for getting state objects from the turn context.
|
||||
*/
|
||||
public class StateTurnContextExtensions
|
||||
{
|
||||
/**
|
||||
* Gets a conversation state object from the turn context.
|
||||
* @param TState The type of the state object to get.
|
||||
* @param context The context object for this turn.
|
||||
* @return The state object.
|
||||
*/
|
||||
public static <TState extends Object> TState GetConversationState(TurnContext context) throws IllegalArgumentException {
|
||||
|
||||
return ConversationState.<TState>Get(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a user state object from the turn context.
|
||||
* @param TState The type of the state object to get.
|
||||
* @param context The context object for this turn.
|
||||
* @return The state object.
|
||||
*/
|
||||
public static <TState> TState GetUserState(TurnContext context) throws IllegalArgumentException {
|
||||
return UserState.<TState>Get(context);
|
||||
}
|
||||
}
|
|
@ -1,35 +1,35 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface Storage
|
||||
{
|
||||
/**
|
||||
* Read StoreItems from storage
|
||||
* @param keys keys of the storeItems to read
|
||||
* @return StoreItem dictionary
|
||||
*/
|
||||
CompletableFuture<Map<String, ? extends Object>> Read(String... keys) throws JsonProcessingException;
|
||||
|
||||
/**
|
||||
* Write StoreItems to storage
|
||||
* @param changes
|
||||
*/
|
||||
CompletableFuture Write(Map<String, ? extends Object> changes) throws Exception;
|
||||
|
||||
/**
|
||||
* Delete StoreItems from storage
|
||||
* @param keys keys of the storeItems to delete
|
||||
*/
|
||||
CompletableFuture Delete(String... keys);
|
||||
}
|
||||
|
||||
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface Storage
|
||||
{
|
||||
/**
|
||||
* Read StoreItems from storage
|
||||
* @param keys keys of the storeItems to read
|
||||
* @return StoreItem dictionary
|
||||
*/
|
||||
CompletableFuture<Map<String, ? extends Object>> Read(String... keys) throws JsonProcessingException;
|
||||
|
||||
/**
|
||||
* Write StoreItems to storage
|
||||
* @param changes
|
||||
*/
|
||||
CompletableFuture Write(Map<String, ? extends Object> changes) throws Exception;
|
||||
|
||||
/**
|
||||
* Delete StoreItems from storage
|
||||
* @param keys keys of the storeItems to delete
|
||||
*/
|
||||
CompletableFuture Delete(String... keys);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,37 +1,37 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
public class StorageExtensions {
|
||||
|
||||
|
||||
/**
|
||||
* Storage extension to Read as strong typed StoreItem objects
|
||||
*
|
||||
* @param StoreItemT
|
||||
* @param storage
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <StoreItemT extends Object> CompletableFuture<Map<String, StoreItemT>> Read(Storage storage, String... keys) throws JsonProcessingException {
|
||||
Map<String, ?> storeItems = storage.Read(keys).join();
|
||||
HashMap<String, StoreItemT> result = new HashMap<String, StoreItemT>();
|
||||
for (Map.Entry entry : storeItems.entrySet()) {
|
||||
StoreItemT tempVal;
|
||||
try {
|
||||
tempVal = (StoreItemT) entry.getValue();
|
||||
} catch (Exception ex) {
|
||||
// Skip - not an instance of StoreItemT (ugly)
|
||||
continue;
|
||||
}
|
||||
result.put((String) entry.getKey(), tempVal);
|
||||
}
|
||||
return CompletableFuture.completedFuture(result);
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
public class StorageExtensions {
|
||||
|
||||
|
||||
/**
|
||||
* Storage extension to Read as strong typed StoreItem objects
|
||||
*
|
||||
* @param StoreItemT
|
||||
* @param storage
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <StoreItemT extends Object> CompletableFuture<Map<String, StoreItemT>> Read(Storage storage, String... keys) throws JsonProcessingException {
|
||||
Map<String, ?> storeItems = storage.Read(keys).join();
|
||||
HashMap<String, StoreItemT> result = new HashMap<String, StoreItemT>();
|
||||
for (Map.Entry entry : storeItems.entrySet()) {
|
||||
StoreItemT tempVal;
|
||||
try {
|
||||
tempVal = (StoreItemT) entry.getValue();
|
||||
} catch (Exception ex) {
|
||||
// Skip - not an instance of StoreItemT (ugly)
|
||||
continue;
|
||||
}
|
||||
result.put((String) entry.getKey(), tempVal);
|
||||
}
|
||||
return CompletableFuture.completedFuture(result);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
public interface StoreItem
|
||||
{
|
||||
/**
|
||||
* eTag for concurrency
|
||||
*/
|
||||
|
||||
String geteTag();
|
||||
void seteTag(String eTag);
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public interface StoreItem
|
||||
{
|
||||
/**
|
||||
* eTag for concurrency
|
||||
*/
|
||||
|
||||
String geteTag();
|
||||
void seteTag(String eTag);
|
||||
}
|
|
@ -1,58 +1,58 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
|
||||
/**
|
||||
* Represents a transcript logger that writes activites to a <see cref="Trace"/> object.
|
||||
*/
|
||||
public class TraceTranscriptLogger implements TranscriptLogger {
|
||||
// https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features
|
||||
private static ObjectMapper mapper = new ObjectMapper()
|
||||
.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
private static final Logger logger = LogManager.getLogger("HelloWorld");
|
||||
|
||||
ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory()
|
||||
{
|
||||
@Override
|
||||
public ForkJoinWorkerThread newThread(ForkJoinPool pool)
|
||||
{
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName("BotTrace-" + worker.getPoolIndex());
|
||||
return worker;
|
||||
}
|
||||
};
|
||||
|
||||
ExecutorService executor = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, true);
|
||||
|
||||
/**
|
||||
* Log an activity to the transcript.
|
||||
*
|
||||
* @param activity The activity to transcribe.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
@Override
|
||||
public void LogActivityAsync(Activity activity) {
|
||||
BotAssert.ActivityNotNull(activity);
|
||||
String event = null;
|
||||
try {
|
||||
event = mapper.writeValueAsString(activity);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.logger.info(event);
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
|
||||
/**
|
||||
* Represents a transcript logger that writes activites to a <see cref="Trace"/> object.
|
||||
*/
|
||||
public class TraceTranscriptLogger implements TranscriptLogger {
|
||||
// https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features
|
||||
private static ObjectMapper mapper = new ObjectMapper()
|
||||
.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
private static final Logger logger = LogManager.getLogger("HelloWorld");
|
||||
|
||||
ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory()
|
||||
{
|
||||
@Override
|
||||
public ForkJoinWorkerThread newThread(ForkJoinPool pool)
|
||||
{
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName("BotTrace-" + worker.getPoolIndex());
|
||||
return worker;
|
||||
}
|
||||
};
|
||||
|
||||
ExecutorService executor = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, true);
|
||||
|
||||
/**
|
||||
* Log an activity to the transcript.
|
||||
*
|
||||
* @param activity The activity to transcribe.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
@Override
|
||||
public void LogActivityAsync(Activity activity) {
|
||||
BotAssert.ActivityNotNull(activity);
|
||||
String event = null;
|
||||
try {
|
||||
event = mapper.writeValueAsString(activity);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.logger.info(event);
|
||||
}
|
||||
}
|
|
@ -1,54 +1,54 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* Transcript store item.
|
||||
*/
|
||||
public class Transcript {
|
||||
/**
|
||||
* channelId that the transcript was taken from.
|
||||
*/
|
||||
private String channelId;
|
||||
|
||||
public String channelId() {
|
||||
return this.channelId;
|
||||
}
|
||||
|
||||
public Transcript withChannelId(String value) {
|
||||
this.channelId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversation id.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Transcript withId(String value) {
|
||||
this.id = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date conversation was started.
|
||||
*/
|
||||
private OffsetDateTime created = OffsetDateTime.now();
|
||||
|
||||
public OffsetDateTime getCreated() {
|
||||
return this.created;
|
||||
}
|
||||
|
||||
public Transcript withCreated(OffsetDateTime value) {
|
||||
this.created = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* Transcript store item.
|
||||
*/
|
||||
public class Transcript {
|
||||
/**
|
||||
* channelId that the transcript was taken from.
|
||||
*/
|
||||
private String channelId;
|
||||
|
||||
public String channelId() {
|
||||
return this.channelId;
|
||||
}
|
||||
|
||||
public Transcript withChannelId(String value) {
|
||||
this.channelId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversation id.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Transcript withId(String value) {
|
||||
this.id = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Date conversation was started.
|
||||
*/
|
||||
private OffsetDateTime created = OffsetDateTime.now();
|
||||
|
||||
public OffsetDateTime getCreated() {
|
||||
return this.created;
|
||||
}
|
||||
|
||||
public Transcript withCreated(OffsetDateTime value) {
|
||||
this.created = value;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
|
||||
/**
|
||||
* Transcript logger stores activities for conversations for recall.
|
||||
*/
|
||||
public interface TranscriptLogger {
|
||||
/**
|
||||
* Log an activity to the transcript.
|
||||
*
|
||||
* @param activity The activity to transcribe.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
void LogActivityAsync(Activity activity);
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
|
||||
/**
|
||||
* Transcript logger stores activities for conversations for recall.
|
||||
*/
|
||||
public interface TranscriptLogger {
|
||||
/**
|
||||
* Log an activity to the transcript.
|
||||
*
|
||||
* @param activity The activity to transcribe.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
void LogActivityAsync(Activity activity);
|
||||
}
|
|
@ -1,191 +1,191 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ActivityTypes;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
|
||||
/**
|
||||
* When added, this middleware will log incoming and outgoing activitites to a ITranscriptStore.
|
||||
*/
|
||||
public class TranscriptLoggerMiddleware implements Middleware {
|
||||
// https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features
|
||||
private static ObjectMapper mapper;
|
||||
|
||||
static {
|
||||
mapper = new ObjectMapper()
|
||||
.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.findAndRegisterModules();
|
||||
}
|
||||
|
||||
private TranscriptLogger logger;
|
||||
private static final Logger log4j = LogManager.getLogger("BotFx");
|
||||
|
||||
private Queue<Activity> transcript = new ConcurrentLinkedQueue<Activity>();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the <see cref="TranscriptLoggerMiddleware"/> class.
|
||||
*
|
||||
* @param transcriptLogger The transcript logger to use.
|
||||
*/
|
||||
public TranscriptLoggerMiddleware(TranscriptLogger transcriptLogger) {
|
||||
if (transcriptLogger == null)
|
||||
throw new NullPointerException("TranscriptLoggerMiddleware requires a ITranscriptLogger implementation. ");
|
||||
|
||||
this.logger = transcriptLogger;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* initialization for middleware turn.
|
||||
*
|
||||
* @param context
|
||||
* @param next
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
// log incoming activity at beginning of turn
|
||||
if (context.getActivity() != null) {
|
||||
JsonNode role = null;
|
||||
if (context.getActivity().from() == null) {
|
||||
throw new RuntimeException("Activity does not contain From field");
|
||||
}
|
||||
if (context.getActivity().from().properties().containsKey("role")) {
|
||||
role = context.getActivity().from().properties().get("role");
|
||||
}
|
||||
|
||||
if (role == null || StringUtils.isBlank(role.asText())) {
|
||||
context.getActivity().from().properties().put("role", mapper.createObjectNode().with("user"));
|
||||
}
|
||||
Activity activityTemp = ActivityImpl.CloneActity(context.getActivity());
|
||||
|
||||
LogActivity(ActivityImpl.CloneActity(context.getActivity()));
|
||||
}
|
||||
|
||||
// hook up onSend pipeline
|
||||
context.OnSendActivities((ctx, activities, nextSend) ->
|
||||
{
|
||||
|
||||
// run full pipeline
|
||||
ResourceResponse[] responses = new ResourceResponse[0];
|
||||
try {
|
||||
if (nextSend != null) {
|
||||
responses = nextSend.call();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Activity activity : activities) {
|
||||
LogActivity(ActivityImpl.CloneActity(activity));
|
||||
}
|
||||
|
||||
return responses;
|
||||
|
||||
|
||||
});
|
||||
|
||||
// hook up update activity pipeline
|
||||
context.OnUpdateActivity((ctx, activity, nextUpdate) ->
|
||||
{
|
||||
|
||||
// run full pipeline
|
||||
ResourceResponse response = null;
|
||||
try {
|
||||
if (nextUpdate != null) {
|
||||
response = nextUpdate.call();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
|
||||
throw new RuntimeException(String.format("Error on Logging.OnUpdateActivity : %s", e.toString()));
|
||||
}
|
||||
|
||||
// add Message Update activity
|
||||
Activity updateActivity = ActivityImpl.CloneActity(activity);
|
||||
updateActivity.withType(ActivityTypes.MESSAGE_UPDATE);
|
||||
LogActivity(updateActivity);
|
||||
return response;
|
||||
|
||||
|
||||
});
|
||||
|
||||
// hook up delete activity pipeline
|
||||
context.OnDeleteActivity((ctxt, reference, nextDel) -> {
|
||||
// run full pipeline
|
||||
|
||||
try {
|
||||
if (nextDel != null) {
|
||||
log4j.error(String.format("Transcript logActivity next delegate: %s)", nextDel));
|
||||
nextDel.run();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log4j.error(String.format("Transcript logActivity failed with %s (next delegate: %s)", e.toString(), nextDel));
|
||||
throw new RuntimeException(String.format("Transcript logActivity failed with %s", e.getMessage()));
|
||||
|
||||
}
|
||||
|
||||
// add MessageDelete activity
|
||||
// log as MessageDelete activity
|
||||
Activity deleteActivity = new Activity()
|
||||
.withType(ActivityTypes.MESSAGE_DELETE)
|
||||
.withId(reference.activityId())
|
||||
.applyConversationReference(reference, false);
|
||||
|
||||
LogActivity(deleteActivity);
|
||||
return;
|
||||
|
||||
});
|
||||
|
||||
|
||||
// process bot logic
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Error on Logging.next : %s", e.toString()));
|
||||
}
|
||||
|
||||
// flush transcript at end of turn
|
||||
while (!transcript.isEmpty()) {
|
||||
Activity activity = transcript.poll();
|
||||
try {
|
||||
this.logger.LogActivityAsync(activity);
|
||||
} catch (RuntimeException err) {
|
||||
log4j.error(String.format("Transcript poll failed : %1$s", err));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void LogActivity(Activity activity) {
|
||||
if (activity.timestamp() == null) {
|
||||
activity.withTimestamp(DateTime.now(DateTimeZone.UTC));
|
||||
}
|
||||
transcript.offer(activity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ActivityTypes;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
|
||||
/**
|
||||
* When added, this middleware will log incoming and outgoing activitites to a ITranscriptStore.
|
||||
*/
|
||||
public class TranscriptLoggerMiddleware implements Middleware {
|
||||
// https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features
|
||||
private static ObjectMapper mapper;
|
||||
|
||||
static {
|
||||
mapper = new ObjectMapper()
|
||||
.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.findAndRegisterModules();
|
||||
}
|
||||
|
||||
private TranscriptLogger logger;
|
||||
private static final Logger log4j = LogManager.getLogger("BotFx");
|
||||
|
||||
private Queue<Activity> transcript = new ConcurrentLinkedQueue<Activity>();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the <see cref="TranscriptLoggerMiddleware"/> class.
|
||||
*
|
||||
* @param transcriptLogger The transcript logger to use.
|
||||
*/
|
||||
public TranscriptLoggerMiddleware(TranscriptLogger transcriptLogger) {
|
||||
if (transcriptLogger == null)
|
||||
throw new NullPointerException("TranscriptLoggerMiddleware requires a ITranscriptLogger implementation. ");
|
||||
|
||||
this.logger = transcriptLogger;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* initialization for middleware turn.
|
||||
*
|
||||
* @param context
|
||||
* @param next
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
// log incoming activity at beginning of turn
|
||||
if (context.getActivity() != null) {
|
||||
JsonNode role = null;
|
||||
if (context.getActivity().from() == null) {
|
||||
throw new RuntimeException("Activity does not contain From field");
|
||||
}
|
||||
if (context.getActivity().from().properties().containsKey("role")) {
|
||||
role = context.getActivity().from().properties().get("role");
|
||||
}
|
||||
|
||||
if (role == null || StringUtils.isBlank(role.asText())) {
|
||||
context.getActivity().from().properties().put("role", mapper.createObjectNode().with("user"));
|
||||
}
|
||||
Activity activityTemp = ActivityImpl.CloneActity(context.getActivity());
|
||||
|
||||
LogActivity(ActivityImpl.CloneActity(context.getActivity()));
|
||||
}
|
||||
|
||||
// hook up onSend pipeline
|
||||
context.OnSendActivities((ctx, activities, nextSend) ->
|
||||
{
|
||||
|
||||
// run full pipeline
|
||||
ResourceResponse[] responses = new ResourceResponse[0];
|
||||
try {
|
||||
if (nextSend != null) {
|
||||
responses = nextSend.call();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Activity activity : activities) {
|
||||
LogActivity(ActivityImpl.CloneActity(activity));
|
||||
}
|
||||
|
||||
return responses;
|
||||
|
||||
|
||||
});
|
||||
|
||||
// hook up update activity pipeline
|
||||
context.OnUpdateActivity((ctx, activity, nextUpdate) ->
|
||||
{
|
||||
|
||||
// run full pipeline
|
||||
ResourceResponse response = null;
|
||||
try {
|
||||
if (nextUpdate != null) {
|
||||
response = nextUpdate.call();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
|
||||
throw new RuntimeException(String.format("Error on Logging.OnUpdateActivity : %s", e.toString()));
|
||||
}
|
||||
|
||||
// add Message Update activity
|
||||
Activity updateActivity = ActivityImpl.CloneActity(activity);
|
||||
updateActivity.withType(ActivityTypes.MESSAGE_UPDATE);
|
||||
LogActivity(updateActivity);
|
||||
return response;
|
||||
|
||||
|
||||
});
|
||||
|
||||
// hook up delete activity pipeline
|
||||
context.OnDeleteActivity((ctxt, reference, nextDel) -> {
|
||||
// run full pipeline
|
||||
|
||||
try {
|
||||
if (nextDel != null) {
|
||||
log4j.error(String.format("Transcript logActivity next delegate: %s)", nextDel));
|
||||
nextDel.run();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log4j.error(String.format("Transcript logActivity failed with %s (next delegate: %s)", e.toString(), nextDel));
|
||||
throw new RuntimeException(String.format("Transcript logActivity failed with %s", e.getMessage()));
|
||||
|
||||
}
|
||||
|
||||
// add MessageDelete activity
|
||||
// log as MessageDelete activity
|
||||
Activity deleteActivity = new Activity()
|
||||
.withType(ActivityTypes.MESSAGE_DELETE)
|
||||
.withId(reference.activityId())
|
||||
.applyConversationReference(reference, false);
|
||||
|
||||
LogActivity(deleteActivity);
|
||||
return;
|
||||
|
||||
});
|
||||
|
||||
|
||||
// process bot logic
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Error on Logging.next : %s", e.toString()));
|
||||
}
|
||||
|
||||
// flush transcript at end of turn
|
||||
while (!transcript.isEmpty()) {
|
||||
Activity activity = transcript.poll();
|
||||
try {
|
||||
this.logger.LogActivityAsync(activity);
|
||||
} catch (RuntimeException err) {
|
||||
log4j.error(String.format("Transcript poll failed : %1$s", err));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void LogActivity(Activity activity) {
|
||||
if (activity.timestamp() == null) {
|
||||
activity.withTimestamp(DateTime.now(DateTimeZone.UTC));
|
||||
}
|
||||
transcript.offer(activity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,57 +1,57 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Transcript logger stores activities for conversations for recall.
|
||||
*/
|
||||
public interface TranscriptStore extends TranscriptLogger {
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @param startDate A cutoff date. Activities older than this date are not included.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
|
||||
CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken);
|
||||
|
||||
CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId);
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: Task<PagedResult<IActivity>> GetTranscriptActivitiesAsync(string channelId, string conversationId, string continuationToken = null, DateTime startDate = default(DateTime));
|
||||
CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken, DateTime localStartDate);
|
||||
|
||||
/**
|
||||
* Gets the conversations on a channel from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @param continuationToken
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
||||
CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId);
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: Task<PagedResult<Transcript>> ListTranscriptsAsync(string channelId, string continuationToken = null);
|
||||
CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId, String continuationToken);
|
||||
|
||||
/**
|
||||
* Deletes conversation data from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture DeleteTranscriptAsync(String channelId, String conversationId);
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Transcript logger stores activities for conversations for recall.
|
||||
*/
|
||||
public interface TranscriptStore extends TranscriptLogger {
|
||||
/**
|
||||
* Gets from the store activities that match a set of criteria.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @param startDate A cutoff date. Activities older than this date are not included.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
|
||||
CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken);
|
||||
|
||||
CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId);
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: Task<PagedResult<IActivity>> GetTranscriptActivitiesAsync(string channelId, string conversationId, string continuationToken = null, DateTime startDate = default(DateTime));
|
||||
CompletableFuture<PagedResult<Activity>> GetTranscriptActivitiesAsync(String channelId, String conversationId, String continuationToken, DateTime localStartDate);
|
||||
|
||||
/**
|
||||
* Gets the conversations on a channel from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @param continuationToken
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
||||
CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId);
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: Task<PagedResult<Transcript>> ListTranscriptsAsync(string channelId, string continuationToken = null);
|
||||
CompletableFuture<PagedResult<Transcript>> ListTranscriptsAsync(String channelId, String continuationToken);
|
||||
|
||||
/**
|
||||
* Deletes conversation data from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture DeleteTranscriptAsync(String channelId, String conversationId);
|
||||
}
|
|
@ -1,182 +1,182 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* A method that can participate in send activity events for the current turn.
|
||||
* @param context The context object for the turn.
|
||||
* @param activities The activities to send.
|
||||
* @param next The delegate to call to continue event processing.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* A handler calls the {@code next} delegate to pass control to
|
||||
* the next registered handler. If a handler doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent handlers and does not send the
|
||||
* {@code activities}.
|
||||
*
|
||||
* {@linkalso BotAdapter}
|
||||
* {@linkalso UpdateActivityHandler}
|
||||
* {@linkalso DeleteActivityHandler}
|
||||
*/
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
//public delegate Task DeleteActivityHandler(TurnContext context, ConversationReference reference, Func<Task> next);
|
||||
|
||||
/**
|
||||
* Provides context for a turn of a bot.
|
||||
* Context provides information needed to process an incoming activity.
|
||||
* The context object is created by a {@link BotAdapter} and persists for the
|
||||
* length of the turn.
|
||||
* {@linkalso Bot}
|
||||
* {@linkalso Middleware}
|
||||
*/
|
||||
public interface TurnContext
|
||||
{
|
||||
/**
|
||||
* Gets the bot adapter that created this context object.
|
||||
*/
|
||||
BotAdapter getAdapter();
|
||||
|
||||
/**
|
||||
* Gets the services registered on this context object.
|
||||
*/
|
||||
TurnContextServiceCollection getServices();
|
||||
|
||||
/**
|
||||
* Incoming request
|
||||
*/
|
||||
Activity getActivity();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether at least one response was sent for the current turn.
|
||||
* @return {@code true} if at least one response was sent for the current turn.
|
||||
*/
|
||||
boolean getResponded();
|
||||
void setResponded(boolean responded);
|
||||
|
||||
/**
|
||||
* Sends a message activity to the sender of the incoming activity.
|
||||
* @param textReplyToSend The text of the message to send.
|
||||
* @param speak Optional, text to be spoken by your bot on a speech-enabled
|
||||
* channel.
|
||||
* @param inputHint Optional, indicates whether your bot is accepting,
|
||||
* expecting, or ignoring user input after the message is delivered to the client.
|
||||
* One of: "acceptingInput", "ignoringInput", or "expectingInput".
|
||||
* Default is "acceptingInput".
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>See the channel's documentation for limits imposed upon the contents of
|
||||
* {@code textReplyToSend}.</p>
|
||||
* <p>To control various characteristics of your bot's speech such as voice,
|
||||
* rate, volume, pronunciation, and pitch, specify {@code speak} in
|
||||
* Speech Synthesis Markup Language (SSML) format.</p>
|
||||
*
|
||||
*/
|
||||
ResourceResponse SendActivity(String textReplyToSend) throws Exception;
|
||||
ResourceResponse SendActivity(String textReplyToSend, String speak) throws Exception;
|
||||
//CompletableFuture<ResourceResponse> SendActivity(String textReplyToSend, String speak = null, String inputHint = InputHints.AcceptingInput);
|
||||
ResourceResponse SendActivity(String textReplyToSend, String speak, String inputHint) throws Exception;
|
||||
|
||||
/**
|
||||
* Sends an activity to the sender of the incoming activity.
|
||||
* @param activity The activity to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
*/
|
||||
ResourceResponse SendActivity(Activity activity) throws Exception;
|
||||
|
||||
/**
|
||||
* Sends a set of activities to the sender of the incoming activity.
|
||||
* @param activities The activities to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activities are successfully sent, the task result contains
|
||||
* an array of {@link ResourceResponse} objects containing the IDs that
|
||||
* the receiving channel assigned to the activities.
|
||||
*/
|
||||
ResourceResponse[] SendActivities(Activity[] activities) throws Exception;
|
||||
|
||||
/**
|
||||
* Replaces an existing activity.
|
||||
* @param activity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>Before calling this, set the ID of the replacement activity to the ID
|
||||
* of the activity to replace.</p>
|
||||
*/
|
||||
ResourceResponse UpdateActivity(Activity activity) throws Exception;
|
||||
|
||||
/**
|
||||
* Replaces an existing activity.
|
||||
* @param activity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>Before calling this, set the ID of the replacement activity to the ID
|
||||
* of the activity to replace.</p>
|
||||
*/
|
||||
//CompletableFuture<ResourceResponse> UpdateActivityAsync(Activity activity) throws Exception;
|
||||
|
||||
/**
|
||||
* Deletes an existing activity.
|
||||
* @param activityId The ID of the activity to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<Void> DeleteActivity(String activityId) throws Exception;
|
||||
|
||||
/**
|
||||
* Deletes an existing activity.
|
||||
* @param conversationReference The conversation containing the activity to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* The conversation reference's {@link ConversationReference.ActivityId}
|
||||
* indicates the activity in the conversation to delete.
|
||||
*/
|
||||
void DeleteActivity(ConversationReference conversationReference) throws Exception;
|
||||
|
||||
/**
|
||||
* Adds a response handler for send activity operations.
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* When the context's {@link SendActivity(Activity)}
|
||||
* or {@link SendActivities(Activity[])} methods are called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*
|
||||
*/
|
||||
TurnContext OnSendActivities(SendActivitiesHandler handler);
|
||||
|
||||
/**
|
||||
* Adds a response handler for update activity operations.
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* When the context's {@link UpdateActivity(Activity)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*
|
||||
*/
|
||||
TurnContext OnUpdateActivity(UpdateActivityHandler handler);
|
||||
|
||||
/**
|
||||
* Adds a response handler for delete activity operations.
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* @throws NullPointerException {@code handler} is {@code null}.
|
||||
* When the context's {@link DeleteActivity(String)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*
|
||||
*/
|
||||
TurnContext OnDeleteActivity(DeleteActivityHandler handler);
|
||||
}
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* A method that can participate in send activity events for the current turn.
|
||||
* @param context The context object for the turn.
|
||||
* @param activities The activities to send.
|
||||
* @param next The delegate to call to continue event processing.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* A handler calls the {@code next} delegate to pass control to
|
||||
* the next registered handler. If a handler doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent handlers and does not send the
|
||||
* {@code activities}.
|
||||
*
|
||||
* {@linkalso BotAdapter}
|
||||
* {@linkalso UpdateActivityHandler}
|
||||
* {@linkalso DeleteActivityHandler}
|
||||
*/
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
//public delegate Task DeleteActivityHandler(TurnContext context, ConversationReference reference, Func<Task> next);
|
||||
|
||||
/**
|
||||
* Provides context for a turn of a bot.
|
||||
* Context provides information needed to process an incoming activity.
|
||||
* The context object is created by a {@link BotAdapter} and persists for the
|
||||
* length of the turn.
|
||||
* {@linkalso Bot}
|
||||
* {@linkalso Middleware}
|
||||
*/
|
||||
public interface TurnContext
|
||||
{
|
||||
/**
|
||||
* Gets the bot adapter that created this context object.
|
||||
*/
|
||||
BotAdapter getAdapter();
|
||||
|
||||
/**
|
||||
* Gets the services registered on this context object.
|
||||
*/
|
||||
TurnContextServiceCollection getServices();
|
||||
|
||||
/**
|
||||
* Incoming request
|
||||
*/
|
||||
Activity getActivity();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether at least one response was sent for the current turn.
|
||||
* @return {@code true} if at least one response was sent for the current turn.
|
||||
*/
|
||||
boolean getResponded();
|
||||
void setResponded(boolean responded);
|
||||
|
||||
/**
|
||||
* Sends a message activity to the sender of the incoming activity.
|
||||
* @param textReplyToSend The text of the message to send.
|
||||
* @param speak Optional, text to be spoken by your bot on a speech-enabled
|
||||
* channel.
|
||||
* @param inputHint Optional, indicates whether your bot is accepting,
|
||||
* expecting, or ignoring user input after the message is delivered to the client.
|
||||
* One of: "acceptingInput", "ignoringInput", or "expectingInput".
|
||||
* Default is "acceptingInput".
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>See the channel's documentation for limits imposed upon the contents of
|
||||
* {@code textReplyToSend}.</p>
|
||||
* <p>To control various characteristics of your bot's speech such as voice,
|
||||
* rate, volume, pronunciation, and pitch, specify {@code speak} in
|
||||
* Speech Synthesis Markup Language (SSML) format.</p>
|
||||
*
|
||||
*/
|
||||
ResourceResponse SendActivity(String textReplyToSend) throws Exception;
|
||||
ResourceResponse SendActivity(String textReplyToSend, String speak) throws Exception;
|
||||
//CompletableFuture<ResourceResponse> SendActivity(String textReplyToSend, String speak = null, String inputHint = InputHints.AcceptingInput);
|
||||
ResourceResponse SendActivity(String textReplyToSend, String speak, String inputHint) throws Exception;
|
||||
|
||||
/**
|
||||
* Sends an activity to the sender of the incoming activity.
|
||||
* @param activity The activity to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
*/
|
||||
ResourceResponse SendActivity(Activity activity) throws Exception;
|
||||
|
||||
/**
|
||||
* Sends a set of activities to the sender of the incoming activity.
|
||||
* @param activities The activities to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activities are successfully sent, the task result contains
|
||||
* an array of {@link ResourceResponse} objects containing the IDs that
|
||||
* the receiving channel assigned to the activities.
|
||||
*/
|
||||
ResourceResponse[] SendActivities(Activity[] activities) throws Exception;
|
||||
|
||||
/**
|
||||
* Replaces an existing activity.
|
||||
* @param activity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>Before calling this, set the ID of the replacement activity to the ID
|
||||
* of the activity to replace.</p>
|
||||
*/
|
||||
ResourceResponse UpdateActivity(Activity activity) throws Exception;
|
||||
|
||||
/**
|
||||
* Replaces an existing activity.
|
||||
* @param activity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>Before calling this, set the ID of the replacement activity to the ID
|
||||
* of the activity to replace.</p>
|
||||
*/
|
||||
//CompletableFuture<ResourceResponse> UpdateActivityAsync(Activity activity) throws Exception;
|
||||
|
||||
/**
|
||||
* Deletes an existing activity.
|
||||
* @param activityId The ID of the activity to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<Void> DeleteActivity(String activityId) throws Exception;
|
||||
|
||||
/**
|
||||
* Deletes an existing activity.
|
||||
* @param conversationReference The conversation containing the activity to delete.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* The conversation reference's {@link ConversationReference.ActivityId}
|
||||
* indicates the activity in the conversation to delete.
|
||||
*/
|
||||
void DeleteActivity(ConversationReference conversationReference) throws Exception;
|
||||
|
||||
/**
|
||||
* Adds a response handler for send activity operations.
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* When the context's {@link SendActivity(Activity)}
|
||||
* or {@link SendActivities(Activity[])} methods are called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*
|
||||
*/
|
||||
TurnContext OnSendActivities(SendActivitiesHandler handler);
|
||||
|
||||
/**
|
||||
* Adds a response handler for update activity operations.
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* When the context's {@link UpdateActivity(Activity)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*
|
||||
*/
|
||||
TurnContext OnUpdateActivity(UpdateActivityHandler handler);
|
||||
|
||||
/**
|
||||
* Adds a response handler for delete activity operations.
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* @throws NullPointerException {@code handler} is {@code null}.
|
||||
* When the context's {@link DeleteActivity(String)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*
|
||||
*/
|
||||
TurnContext OnDeleteActivity(DeleteActivityHandler handler);
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,32 +1,32 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a set of collection of services associated with the {@link TurnContext}.
|
||||
*
|
||||
* TODO: add more details on what kind of services can/should be stored here, by whom and what the lifetime semantics are, etc.
|
||||
*
|
||||
*/
|
||||
public interface TurnContextServiceCollection extends Iterable<Map.Entry<String, Object>>, AutoCloseable {
|
||||
/**
|
||||
* Add a service with a specified key.
|
||||
* @param TService The type of service to be added.
|
||||
* @param key The key to store the service under.
|
||||
* @param service The service to add.
|
||||
* @throws IllegalArgumentException Thrown when a service is already registered with the specified {@code key}
|
||||
*/
|
||||
<TService extends Object> void Add(String key, TService service) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Get a service by its key.
|
||||
* @param TService The type of service to be retrieved.
|
||||
* @param key The key of the service to get.
|
||||
* @return The service stored under the specified key.
|
||||
*/
|
||||
<TService extends Object> TService Get(String key) throws IllegalArgumentException;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a set of collection of services associated with the {@link TurnContext}.
|
||||
*
|
||||
* TODO: add more details on what kind of services can/should be stored here, by whom and what the lifetime semantics are, etc.
|
||||
*
|
||||
*/
|
||||
public interface TurnContextServiceCollection extends Iterable<Map.Entry<String, Object>>, AutoCloseable {
|
||||
/**
|
||||
* Add a service with a specified key.
|
||||
* @param TService The type of service to be added.
|
||||
* @param key The key to store the service under.
|
||||
* @param service The service to add.
|
||||
* @throws IllegalArgumentException Thrown when a service is already registered with the specified {@code key}
|
||||
*/
|
||||
<TService extends Object> void Add(String key, TService service) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Get a service by its key.
|
||||
* @param TService The type of service to be retrieved.
|
||||
* @param key The key of the service to get.
|
||||
* @return The service stored under the specified key.
|
||||
*/
|
||||
<TService extends Object> TService Get(String key) throws IllegalArgumentException;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,67 +1,67 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public final class TurnContextServiceCollectionImpl implements TurnContextServiceCollection, AutoCloseable
|
||||
{
|
||||
private final HashMap<String, Object> _services = new HashMap<String, Object>();
|
||||
|
||||
public TurnContextServiceCollectionImpl() throws IllegalArgumentException {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public <TService extends Object> TService Get(String key) throws IllegalArgumentException {
|
||||
if (key == null)
|
||||
throw new IllegalArgumentException("key");
|
||||
|
||||
TService service = (TService) _services.get(key);
|
||||
// TODO: log that we didn't find the requested service
|
||||
return (TService) service;
|
||||
}
|
||||
/**
|
||||
* Get a service by type using its full type name as the key.
|
||||
* @param TService The type of service to be retrieved.
|
||||
* @return The service stored under the specified key.
|
||||
*/
|
||||
public <TService> TService Get(Class<TService> type) throws IllegalArgumentException {
|
||||
return this.Get(type.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TService extends Object> void Add(String key, TService service) throws IllegalArgumentException {
|
||||
if (key == null) throw new IllegalArgumentException("key");
|
||||
if (service == null) throw new IllegalArgumentException("service");
|
||||
|
||||
if (_services.containsKey(key))
|
||||
throw new IllegalArgumentException (String.format("Key %s already exists", key));
|
||||
_services.put(key, service);
|
||||
}
|
||||
/**
|
||||
* Add a service using its full type name as the key.
|
||||
* @param TService The type of service to be added.
|
||||
* @param service The service to add.
|
||||
*/
|
||||
|
||||
public <TService> void Add(TService service, Class<TService> type) throws IllegalArgumentException {
|
||||
Add(type.getName(), service);
|
||||
}
|
||||
|
||||
|
||||
public Iterator<Map.Entry<String, Object>> iterator() {
|
||||
return _services.entrySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
for (Map.Entry entry : this._services.entrySet()) {
|
||||
if (entry.getValue() instanceof AutoCloseable) {
|
||||
((AutoCloseable) entry.getValue()).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public final class TurnContextServiceCollectionImpl implements TurnContextServiceCollection, AutoCloseable
|
||||
{
|
||||
private final HashMap<String, Object> _services = new HashMap<String, Object>();
|
||||
|
||||
public TurnContextServiceCollectionImpl() throws IllegalArgumentException {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public <TService extends Object> TService Get(String key) throws IllegalArgumentException {
|
||||
if (key == null)
|
||||
throw new IllegalArgumentException("key");
|
||||
|
||||
TService service = (TService) _services.get(key);
|
||||
// TODO: log that we didn't find the requested service
|
||||
return (TService) service;
|
||||
}
|
||||
/**
|
||||
* Get a service by type using its full type name as the key.
|
||||
* @param TService The type of service to be retrieved.
|
||||
* @return The service stored under the specified key.
|
||||
*/
|
||||
public <TService> TService Get(Class<TService> type) throws IllegalArgumentException {
|
||||
return this.Get(type.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TService extends Object> void Add(String key, TService service) throws IllegalArgumentException {
|
||||
if (key == null) throw new IllegalArgumentException("key");
|
||||
if (service == null) throw new IllegalArgumentException("service");
|
||||
|
||||
if (_services.containsKey(key))
|
||||
throw new IllegalArgumentException (String.format("Key %s already exists", key));
|
||||
_services.put(key, service);
|
||||
}
|
||||
/**
|
||||
* Add a service using its full type name as the key.
|
||||
* @param TService The type of service to be added.
|
||||
* @param service The service to add.
|
||||
*/
|
||||
|
||||
public <TService> void Add(TService service, Class<TService> type) throws IllegalArgumentException {
|
||||
Add(type.getName(), service);
|
||||
}
|
||||
|
||||
|
||||
public Iterator<Map.Entry<String, Object>> iterator() {
|
||||
return _services.entrySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
for (Map.Entry entry : this._services.entrySet()) {
|
||||
if (entry.getValue() instanceof AutoCloseable) {
|
||||
((AutoCloseable) entry.getValue()).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TurnTask {
|
||||
CompletableFuture invoke(TurnContext context);
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TurnTask {
|
||||
CompletableFuture invoke(TurnContext context);
|
||||
}
|
|
@ -1,30 +1,30 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* A method that can participate in update activity events for the current turn.
|
||||
* @param context The context object for the turn.
|
||||
* @param activity The replacement activity.
|
||||
* @param next The delegate to call to continue event processing.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* A handler calls the {@code next} delegate to pass control to
|
||||
* the next registered handler. If a handler doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent handlers and does not update the
|
||||
* activity.
|
||||
* <p>The activity's {@link Activity.Id} indicates the activity in the
|
||||
* conversation to replace.</p>
|
||||
*
|
||||
* {@linkalso BotAdapter}
|
||||
* {@linkalso SendActivitiesHandler}
|
||||
* {@linkalso DeleteActivityHandler}
|
||||
*/
|
||||
|
||||
@FunctionalInterface
|
||||
public interface UpdateActivityHandler {
|
||||
ResourceResponse handle(TurnContext context, Activity activity, Callable<ResourceResponse> next);
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* A method that can participate in update activity events for the current turn.
|
||||
* @param context The context object for the turn.
|
||||
* @param activity The replacement activity.
|
||||
* @param next The delegate to call to continue event processing.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* A handler calls the {@code next} delegate to pass control to
|
||||
* the next registered handler. If a handler doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent handlers and does not update the
|
||||
* activity.
|
||||
* <p>The activity's {@link Activity.Id} indicates the activity in the
|
||||
* conversation to replace.</p>
|
||||
*
|
||||
* {@linkalso BotAdapter}
|
||||
* {@linkalso SendActivitiesHandler}
|
||||
* {@linkalso DeleteActivityHandler}
|
||||
*/
|
||||
|
||||
@FunctionalInterface
|
||||
public interface UpdateActivityHandler {
|
||||
ResourceResponse handle(TurnContext context, Activity activity, Callable<ResourceResponse> next);
|
||||
}
|
|
@ -1,50 +1,50 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.StateSettings;
|
||||
import com.microsoft.bot.builder.Storage;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Handles persistence of a user state object using the user ID as part of the key.
|
||||
* @param TState The type of the user state object.
|
||||
*/
|
||||
public class UserState<TState> extends BotState<TState>
|
||||
{
|
||||
/**
|
||||
* The key to use to read and write this conversation state object to storage.
|
||||
*/
|
||||
// Note: Hard coded to maintain compatibility with C#
|
||||
// "UserState:{typeof(UserState<TState>).Namespace}.{typeof(UserState<TState>).Name}"
|
||||
public static String PropertyName() {
|
||||
return String.format("UserState:Microsoft.Bot.Builder.Core.Extensions.UserState`1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link UserState{TState}} object.
|
||||
* @param storage The storage provider to use.
|
||||
* @param settings The state persistance options to use.
|
||||
*/
|
||||
public UserState(Storage storage, Supplier<? extends TState> ctor) {
|
||||
this(storage, ctor, null);
|
||||
}
|
||||
public UserState(Storage storage, Supplier<? extends TState> ctor, StateSettings settings) {
|
||||
super(storage, PropertyName(),
|
||||
(context) -> {
|
||||
return String.format("user/%s/%s", context.getActivity().channelId(), context.getActivity().conversation().id());
|
||||
},
|
||||
ctor,
|
||||
settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user state object from turn context.
|
||||
* @param context The context object for this turn.
|
||||
* @return The user state object.
|
||||
*/
|
||||
public static <TState> TState Get(TurnContext context) throws IllegalArgumentException {
|
||||
return context.getServices().<TState>Get(PropertyName());
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.StateSettings;
|
||||
import com.microsoft.bot.builder.Storage;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Handles persistence of a user state object using the user ID as part of the key.
|
||||
* @param TState The type of the user state object.
|
||||
*/
|
||||
public class UserState<TState> extends BotState<TState>
|
||||
{
|
||||
/**
|
||||
* The key to use to read and write this conversation state object to storage.
|
||||
*/
|
||||
// Note: Hard coded to maintain compatibility with C#
|
||||
// "UserState:{typeof(UserState<TState>).Namespace}.{typeof(UserState<TState>).Name}"
|
||||
public static String PropertyName() {
|
||||
return String.format("UserState:Microsoft.Bot.Builder.Core.Extensions.UserState`1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link UserState{TState}} object.
|
||||
* @param storage The storage provider to use.
|
||||
* @param settings The state persistance options to use.
|
||||
*/
|
||||
public UserState(Storage storage, Supplier<? extends TState> ctor) {
|
||||
this(storage, ctor, null);
|
||||
}
|
||||
public UserState(Storage storage, Supplier<? extends TState> ctor, StateSettings settings) {
|
||||
super(storage, PropertyName(),
|
||||
(context) -> {
|
||||
return String.format("user/%s/%s", context.getActivity().channelId(), context.getActivity().conversation().id());
|
||||
},
|
||||
ctor,
|
||||
settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user state object from turn context.
|
||||
* @param context The context object for this turn.
|
||||
* @return The user state object.
|
||||
*/
|
||||
public static <TState> TState Get(TurnContext context) throws IllegalArgumentException {
|
||||
return context.getServices().<TState>Get(PropertyName());
|
||||
}
|
||||
}
|
|
@ -1,234 +1,234 @@
|
|||
package com.microsoft.bot.builder.adapters;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import com.microsoft.bot.builder.BotAdapter;
|
||||
import com.microsoft.bot.builder.Middleware;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.builder.TurnContextImpl;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TestAdapter extends BotAdapter {
|
||||
private int nextId = 0;
|
||||
private final Queue<Activity> botReplies = new LinkedList<>();
|
||||
private ConversationReference conversationReference;
|
||||
|
||||
public TestAdapter() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
|
||||
public TestAdapter(ConversationReference reference) {
|
||||
if (reference != null) {
|
||||
this.withConversationReference(reference);
|
||||
} else {
|
||||
this.withConversationReference(new ConversationReference()
|
||||
.withChannelId("test")
|
||||
.withServiceUrl("https://test.com"));
|
||||
|
||||
this.conversationReference().withUser(new ChannelAccount()
|
||||
.withId("user1")
|
||||
.withName("User1"));
|
||||
this.conversationReference().withBot(new ChannelAccount()
|
||||
.withId("bot")
|
||||
.withName("Bot"));
|
||||
this.conversationReference().withConversation(new ConversationAccount()
|
||||
.withIsGroup(Boolean.FALSE)
|
||||
.withConversationType("convo1")
|
||||
.withId("Conversation1"));
|
||||
}
|
||||
}
|
||||
|
||||
public Queue<Activity> activeQueue() {
|
||||
return botReplies;
|
||||
}
|
||||
|
||||
public TestAdapter Use(Middleware middleware) {
|
||||
super.Use(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ProcessActivity(ActivityImpl activity,
|
||||
Consumer<TurnContext> callback
|
||||
) throws Exception {
|
||||
synchronized (this.conversationReference()) {
|
||||
// ready for next reply
|
||||
if (activity.type() == null)
|
||||
activity.withType(ActivityTypes.MESSAGE);
|
||||
activity.withChannelId(this.conversationReference().channelId());
|
||||
activity.withFrom(this.conversationReference().user());
|
||||
activity.withRecipient(this.conversationReference().bot());
|
||||
activity.withConversation(this.conversationReference().conversation());
|
||||
activity.withServiceUrl(this.conversationReference().serviceUrl());
|
||||
Integer next = this.nextId++;
|
||||
activity.withId(next.toString());
|
||||
}
|
||||
// Assume Default DateTime : DateTime(0)
|
||||
if (activity.timestamp() == null || activity.timestamp() == new DateTime(0))
|
||||
activity.withTimestamp(DateTime.now());
|
||||
|
||||
try (TurnContextImpl context = new TurnContextImpl(this, activity)) {
|
||||
super.RunPipeline(context, callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public ConversationReference conversationReference() {
|
||||
return conversationReference;
|
||||
}
|
||||
|
||||
public void withConversationReference(ConversationReference conversationReference) {
|
||||
this.conversationReference = conversationReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceResponse[] SendActivities(TurnContext context, Activity[] activities) throws InterruptedException {
|
||||
List<ResourceResponse> responses = new LinkedList<ResourceResponse>();
|
||||
|
||||
for (Activity activity : activities) {
|
||||
if (StringUtils.isEmpty(activity.id()))
|
||||
activity.withId(UUID.randomUUID().toString());
|
||||
|
||||
if (activity.timestamp() == null)
|
||||
activity.withTimestamp(DateTime.now());
|
||||
|
||||
responses.add(new ResourceResponse().withId(activity.id()));
|
||||
// This is simulating DELAY
|
||||
|
||||
System.out.println(String.format("TestAdapter:SendActivities(tid:%s):Count:%s", Thread.currentThread().getId(), activities.length));
|
||||
for (Activity act : activities) {
|
||||
System.out.printf(":--------\n: To:%s\n", act.recipient().name());
|
||||
System.out.printf(": From:%s\n", (act.from() == null) ? "No from set" : act.from().name());
|
||||
System.out.printf(": Text:%s\n:---------", (act.text() == null) ? "No text set" : act.text());
|
||||
}
|
||||
if (activity.type().toString().equals("delay")) {
|
||||
// The BotFrameworkAdapter and Console adapter implement this
|
||||
// hack directly in the POST method. Replicating that here
|
||||
// to keep the behavior as close as possible to facillitate
|
||||
// more realistic tests.
|
||||
int delayMs = (int) activity.value();
|
||||
Thread.sleep(delayMs);
|
||||
} else {
|
||||
synchronized (this.botReplies) {
|
||||
this.botReplies.add(activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
return responses.toArray(new ResourceResponse[responses.size()]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceResponse UpdateActivity(TurnContext context, Activity activity) {
|
||||
synchronized (this.botReplies) {
|
||||
List<Activity> replies = new ArrayList<>(botReplies);
|
||||
for (int i = 0; i < this.botReplies.size(); i++) {
|
||||
if (replies.get(i).id().equals(activity.id())) {
|
||||
replies.set(i, activity);
|
||||
this.botReplies.clear();
|
||||
|
||||
for (Activity item : replies) {
|
||||
this.botReplies.add(item);
|
||||
}
|
||||
return new ResourceResponse().withId(activity.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ResourceResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DeleteActivity(TurnContext context, ConversationReference reference) {
|
||||
synchronized (this.botReplies) {
|
||||
ArrayList<Activity> replies = new ArrayList<>(this.botReplies);
|
||||
for (int i = 0; i < this.botReplies.size(); i++) {
|
||||
if (replies.get(i).id().equals(reference.activityId())) {
|
||||
replies.remove(i);
|
||||
this.botReplies.clear();
|
||||
for (Activity item : replies) {
|
||||
this.botReplies.add(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: this resets the queue, it doesn't actually maintain multiple converstion queues
|
||||
*
|
||||
* @param channelId
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
//@Override
|
||||
public CompletableFuture CreateConversation(String channelId, Function<TurnContext, CompletableFuture> callback) {
|
||||
this.activeQueue().clear();
|
||||
MessageActivity update = MessageActivity.CreateConversationUpdateActivity();
|
||||
|
||||
update.withConversation(new ConversationAccount().withId(UUID.randomUUID().toString()));
|
||||
TurnContextImpl context = new TurnContextImpl(this, (ActivityImpl) update);
|
||||
return callback.apply(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by TestFlow to check next reply
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Activity GetNextReply() {
|
||||
synchronized (this.botReplies) {
|
||||
if (this.botReplies.size() > 0) {
|
||||
return this.botReplies.remove();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by TestFlow to get appropriate activity for conversationReference of testbot
|
||||
*
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
public Activity MakeActivity() {
|
||||
return MakeActivity(null);
|
||||
}
|
||||
|
||||
public ActivityImpl MakeActivity(String text) {
|
||||
Integer next = nextId++;
|
||||
ActivityImpl activity = (ActivityImpl) new ActivityImpl()
|
||||
.withType(ActivityTypes.MESSAGE)
|
||||
.withFrom(conversationReference().user())
|
||||
.withRecipient(conversationReference().bot())
|
||||
.withConversation(conversationReference().conversation())
|
||||
.withServiceUrl(conversationReference().serviceUrl())
|
||||
.withId(next.toString())
|
||||
.withText(text);
|
||||
|
||||
return activity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by TestFlow to send text to the bot
|
||||
*
|
||||
* @param userSays
|
||||
* @return
|
||||
*/
|
||||
public void SendTextToBot(String userSays, Consumer<TurnContext> callback) throws Exception {
|
||||
this.ProcessActivity(this.MakeActivity(userSays), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
package com.microsoft.bot.builder.adapters;
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import com.microsoft.bot.builder.BotAdapter;
|
||||
import com.microsoft.bot.builder.Middleware;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.builder.TurnContextImpl;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TestAdapter extends BotAdapter {
|
||||
private int nextId = 0;
|
||||
private final Queue<Activity> botReplies = new LinkedList<>();
|
||||
private ConversationReference conversationReference;
|
||||
|
||||
public TestAdapter() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
|
||||
public TestAdapter(ConversationReference reference) {
|
||||
if (reference != null) {
|
||||
this.withConversationReference(reference);
|
||||
} else {
|
||||
this.withConversationReference(new ConversationReference()
|
||||
.withChannelId("test")
|
||||
.withServiceUrl("https://test.com"));
|
||||
|
||||
this.conversationReference().withUser(new ChannelAccount()
|
||||
.withId("user1")
|
||||
.withName("User1"));
|
||||
this.conversationReference().withBot(new ChannelAccount()
|
||||
.withId("bot")
|
||||
.withName("Bot"));
|
||||
this.conversationReference().withConversation(new ConversationAccount()
|
||||
.withIsGroup(Boolean.FALSE)
|
||||
.withConversationType("convo1")
|
||||
.withId("Conversation1"));
|
||||
}
|
||||
}
|
||||
|
||||
public Queue<Activity> activeQueue() {
|
||||
return botReplies;
|
||||
}
|
||||
|
||||
public TestAdapter Use(Middleware middleware) {
|
||||
super.Use(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ProcessActivity(ActivityImpl activity,
|
||||
Consumer<TurnContext> callback
|
||||
) throws Exception {
|
||||
synchronized (this.conversationReference()) {
|
||||
// ready for next reply
|
||||
if (activity.type() == null)
|
||||
activity.withType(ActivityTypes.MESSAGE);
|
||||
activity.withChannelId(this.conversationReference().channelId());
|
||||
activity.withFrom(this.conversationReference().user());
|
||||
activity.withRecipient(this.conversationReference().bot());
|
||||
activity.withConversation(this.conversationReference().conversation());
|
||||
activity.withServiceUrl(this.conversationReference().serviceUrl());
|
||||
Integer next = this.nextId++;
|
||||
activity.withId(next.toString());
|
||||
}
|
||||
// Assume Default DateTime : DateTime(0)
|
||||
if (activity.timestamp() == null || activity.timestamp() == new DateTime(0))
|
||||
activity.withTimestamp(DateTime.now());
|
||||
|
||||
try (TurnContextImpl context = new TurnContextImpl(this, activity)) {
|
||||
super.RunPipeline(context, callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public ConversationReference conversationReference() {
|
||||
return conversationReference;
|
||||
}
|
||||
|
||||
public void withConversationReference(ConversationReference conversationReference) {
|
||||
this.conversationReference = conversationReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceResponse[] SendActivities(TurnContext context, Activity[] activities) throws InterruptedException {
|
||||
List<ResourceResponse> responses = new LinkedList<ResourceResponse>();
|
||||
|
||||
for (Activity activity : activities) {
|
||||
if (StringUtils.isEmpty(activity.id()))
|
||||
activity.withId(UUID.randomUUID().toString());
|
||||
|
||||
if (activity.timestamp() == null)
|
||||
activity.withTimestamp(DateTime.now());
|
||||
|
||||
responses.add(new ResourceResponse().withId(activity.id()));
|
||||
// This is simulating DELAY
|
||||
|
||||
System.out.println(String.format("TestAdapter:SendActivities(tid:%s):Count:%s", Thread.currentThread().getId(), activities.length));
|
||||
for (Activity act : activities) {
|
||||
System.out.printf(":--------\n: To:%s\n", act.recipient().name());
|
||||
System.out.printf(": From:%s\n", (act.from() == null) ? "No from set" : act.from().name());
|
||||
System.out.printf(": Text:%s\n:---------", (act.text() == null) ? "No text set" : act.text());
|
||||
}
|
||||
if (activity.type().toString().equals("delay")) {
|
||||
// The BotFrameworkAdapter and Console adapter implement this
|
||||
// hack directly in the POST method. Replicating that here
|
||||
// to keep the behavior as close as possible to facillitate
|
||||
// more realistic tests.
|
||||
int delayMs = (int) activity.value();
|
||||
Thread.sleep(delayMs);
|
||||
} else {
|
||||
synchronized (this.botReplies) {
|
||||
this.botReplies.add(activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
return responses.toArray(new ResourceResponse[responses.size()]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceResponse UpdateActivity(TurnContext context, Activity activity) {
|
||||
synchronized (this.botReplies) {
|
||||
List<Activity> replies = new ArrayList<>(botReplies);
|
||||
for (int i = 0; i < this.botReplies.size(); i++) {
|
||||
if (replies.get(i).id().equals(activity.id())) {
|
||||
replies.set(i, activity);
|
||||
this.botReplies.clear();
|
||||
|
||||
for (Activity item : replies) {
|
||||
this.botReplies.add(item);
|
||||
}
|
||||
return new ResourceResponse().withId(activity.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ResourceResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DeleteActivity(TurnContext context, ConversationReference reference) {
|
||||
synchronized (this.botReplies) {
|
||||
ArrayList<Activity> replies = new ArrayList<>(this.botReplies);
|
||||
for (int i = 0; i < this.botReplies.size(); i++) {
|
||||
if (replies.get(i).id().equals(reference.activityId())) {
|
||||
replies.remove(i);
|
||||
this.botReplies.clear();
|
||||
for (Activity item : replies) {
|
||||
this.botReplies.add(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: this resets the queue, it doesn't actually maintain multiple converstion queues
|
||||
*
|
||||
* @param channelId
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
//@Override
|
||||
public CompletableFuture CreateConversation(String channelId, Function<TurnContext, CompletableFuture> callback) {
|
||||
this.activeQueue().clear();
|
||||
MessageActivity update = MessageActivity.CreateConversationUpdateActivity();
|
||||
|
||||
update.withConversation(new ConversationAccount().withId(UUID.randomUUID().toString()));
|
||||
TurnContextImpl context = new TurnContextImpl(this, (ActivityImpl) update);
|
||||
return callback.apply(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by TestFlow to check next reply
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Activity GetNextReply() {
|
||||
synchronized (this.botReplies) {
|
||||
if (this.botReplies.size() > 0) {
|
||||
return this.botReplies.remove();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by TestFlow to get appropriate activity for conversationReference of testbot
|
||||
*
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
public Activity MakeActivity() {
|
||||
return MakeActivity(null);
|
||||
}
|
||||
|
||||
public ActivityImpl MakeActivity(String text) {
|
||||
Integer next = nextId++;
|
||||
ActivityImpl activity = (ActivityImpl) new ActivityImpl()
|
||||
.withType(ActivityTypes.MESSAGE)
|
||||
.withFrom(conversationReference().user())
|
||||
.withRecipient(conversationReference().bot())
|
||||
.withConversation(conversationReference().conversation())
|
||||
.withServiceUrl(conversationReference().serviceUrl())
|
||||
.withId(next.toString())
|
||||
.withText(text);
|
||||
|
||||
return activity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by TestFlow to send text to the bot
|
||||
*
|
||||
* @param userSays
|
||||
* @return
|
||||
*/
|
||||
public void SendTextToBot(String userSays, Consumer<TurnContext> callback) throws Exception {
|
||||
this.ProcessActivity(this.MakeActivity(userSays), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,111 +1,111 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
|
||||
import com.microsoft.bot.builder.BotAssert;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Base class for controls
|
||||
*/
|
||||
public abstract class Dialog
|
||||
{
|
||||
/**
|
||||
* Starts the dialog. Depending on the dialog, its possible for the dialog to finish
|
||||
* immediately so it's advised to check the completion Object returned by `begin()` and ensure
|
||||
* that the dialog is still active before continuing.
|
||||
* @param context Context for the current turn of the conversation with the user.
|
||||
* @param state A state Object that the dialog will use to persist its current state. This should be an empty Object which the dialog will populate. The bot should persist this with its other conversation state for as long as the dialog is still active.
|
||||
* @param options (Optional) additional options supported by the dialog.
|
||||
* @return DialogCompletion result
|
||||
*/
|
||||
public CompletableFuture<DialogCompletion> Begin(TurnContext context, HashMap<String, Object> state)
|
||||
{
|
||||
return Begin(context, state, null);
|
||||
}
|
||||
public CompletableFuture<DialogCompletion> Begin(TurnContext context, HashMap<String, Object> state, HashMap<String, Object> options)
|
||||
{
|
||||
BotAssert.ContextNotNull(context);
|
||||
if (state == null)
|
||||
throw new NullPointerException("HashMap<String, Object> state");
|
||||
|
||||
// Create empty dialog set and ourselves to it
|
||||
// TODO: Complete
|
||||
//DialogSet dialogs = new DialogSet();
|
||||
//dialogs.Add("dialog", (IDialog)this);
|
||||
|
||||
// Start the control
|
||||
//HashMap<String, Object> result = null;
|
||||
|
||||
/*
|
||||
// TODO Complete
|
||||
|
||||
await dc.Begin("dialog", options);
|
||||
*/
|
||||
CompletableFuture<DialogCompletion> result = null;
|
||||
/*
|
||||
if (dc.ActiveDialog != null) {
|
||||
result = new DialogCompletion();
|
||||
result.setIsActive(true);
|
||||
result.setIsCompleted(false);
|
||||
}
|
||||
else{
|
||||
result = new DialogCompletion();
|
||||
result.setIsActive(false);
|
||||
result.setIsCompleted(true);
|
||||
result.setResult(result);
|
||||
}
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes a users reply to the dialog for further processing.The bot should keep calling
|
||||
* 'continue()' for future turns until the dialog returns a completion Object with
|
||||
* 'isCompleted == true'. To cancel or interrupt the prompt simply delete the `state` Object
|
||||
* being persisted.
|
||||
* @param context Context for the current turn of the conversation with the user.
|
||||
* @param state A state Object that was previously initialized by a call to [begin()](#begin).
|
||||
* @return DialogCompletion result
|
||||
*/
|
||||
public CompletableFuture<DialogCompletion> Continue(TurnContext context, HashMap<String, Object> state)
|
||||
{
|
||||
BotAssert.ContextNotNull(context);
|
||||
if (state == null)
|
||||
throw new NullPointerException("HashMap<String, Object>");
|
||||
|
||||
// Create empty dialog set and ourselves to it
|
||||
// TODO: daveta
|
||||
//DialogSet dialogs = new DialogSet();
|
||||
//dialogs.Add("dialog", (IDialog)this);
|
||||
|
||||
// Continue the dialog
|
||||
//HashMap<String, Object> result = null;
|
||||
CompletableFuture<DialogCompletion> result = null;
|
||||
/*
|
||||
TODO: daveta
|
||||
var dc = new DialogContext(dialogs, context, state, (r) => { result = r; });
|
||||
if (dc.ActiveDialog != null)
|
||||
{
|
||||
await dc.Continue();
|
||||
return dc.ActiveDialog != null
|
||||
?
|
||||
new DialogCompletion { IsActive = true, IsCompleted = false }
|
||||
:
|
||||
new DialogCompletion { IsActive = false, IsCompleted = true, Result = result };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DialogCompletion { IsActive = false, IsCompleted = false };
|
||||
}
|
||||
*/
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
|
||||
import com.microsoft.bot.builder.BotAssert;
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Base class for controls
|
||||
*/
|
||||
public abstract class Dialog
|
||||
{
|
||||
/**
|
||||
* Starts the dialog. Depending on the dialog, its possible for the dialog to finish
|
||||
* immediately so it's advised to check the completion Object returned by `begin()` and ensure
|
||||
* that the dialog is still active before continuing.
|
||||
* @param context Context for the current turn of the conversation with the user.
|
||||
* @param state A state Object that the dialog will use to persist its current state. This should be an empty Object which the dialog will populate. The bot should persist this with its other conversation state for as long as the dialog is still active.
|
||||
* @param options (Optional) additional options supported by the dialog.
|
||||
* @return DialogCompletion result
|
||||
*/
|
||||
public CompletableFuture<DialogCompletion> Begin(TurnContext context, HashMap<String, Object> state)
|
||||
{
|
||||
return Begin(context, state, null);
|
||||
}
|
||||
public CompletableFuture<DialogCompletion> Begin(TurnContext context, HashMap<String, Object> state, HashMap<String, Object> options)
|
||||
{
|
||||
BotAssert.ContextNotNull(context);
|
||||
if (state == null)
|
||||
throw new NullPointerException("HashMap<String, Object> state");
|
||||
|
||||
// Create empty dialog set and ourselves to it
|
||||
// TODO: Complete
|
||||
//DialogSet dialogs = new DialogSet();
|
||||
//dialogs.Add("dialog", (IDialog)this);
|
||||
|
||||
// Start the control
|
||||
//HashMap<String, Object> result = null;
|
||||
|
||||
/*
|
||||
// TODO Complete
|
||||
|
||||
await dc.Begin("dialog", options);
|
||||
*/
|
||||
CompletableFuture<DialogCompletion> result = null;
|
||||
/*
|
||||
if (dc.ActiveDialog != null) {
|
||||
result = new DialogCompletion();
|
||||
result.setIsActive(true);
|
||||
result.setIsCompleted(false);
|
||||
}
|
||||
else{
|
||||
result = new DialogCompletion();
|
||||
result.setIsActive(false);
|
||||
result.setIsCompleted(true);
|
||||
result.setResult(result);
|
||||
}
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes a users reply to the dialog for further processing.The bot should keep calling
|
||||
* 'continue()' for future turns until the dialog returns a completion Object with
|
||||
* 'isCompleted == true'. To cancel or interrupt the prompt simply delete the `state` Object
|
||||
* being persisted.
|
||||
* @param context Context for the current turn of the conversation with the user.
|
||||
* @param state A state Object that was previously initialized by a call to [begin()](#begin).
|
||||
* @return DialogCompletion result
|
||||
*/
|
||||
public CompletableFuture<DialogCompletion> Continue(TurnContext context, HashMap<String, Object> state)
|
||||
{
|
||||
BotAssert.ContextNotNull(context);
|
||||
if (state == null)
|
||||
throw new NullPointerException("HashMap<String, Object>");
|
||||
|
||||
// Create empty dialog set and ourselves to it
|
||||
// TODO: daveta
|
||||
//DialogSet dialogs = new DialogSet();
|
||||
//dialogs.Add("dialog", (IDialog)this);
|
||||
|
||||
// Continue the dialog
|
||||
//HashMap<String, Object> result = null;
|
||||
CompletableFuture<DialogCompletion> result = null;
|
||||
/*
|
||||
TODO: daveta
|
||||
var dc = new DialogContext(dialogs, context, state, (r) => { result = r; });
|
||||
if (dc.ActiveDialog != null)
|
||||
{
|
||||
await dc.Continue();
|
||||
return dc.ActiveDialog != null
|
||||
?
|
||||
new DialogCompletion { IsActive = true, IsCompleted = false }
|
||||
:
|
||||
new DialogCompletion { IsActive = false, IsCompleted = true, Result = result };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DialogCompletion { IsActive = false, IsCompleted = false };
|
||||
}
|
||||
*/
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +1,54 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Result returned to the caller of one of the various stack manipulation methods and used to
|
||||
* return the result from a final call to `DialogContext.end()` to the bots logic.
|
||||
*/
|
||||
public class DialogCompletion
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* If 'true' the dialog is still active.
|
||||
*/
|
||||
boolean _isActive;
|
||||
public void setIsActive(boolean isActive) {
|
||||
this._isActive = isActive;
|
||||
}
|
||||
public boolean getIsActive() {
|
||||
return this._isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* If 'true' the dialog just completed and the final [result](#result) can be retrieved.
|
||||
*/
|
||||
boolean _isCompleted;
|
||||
public void setIsCompleted(boolean isCompleted)
|
||||
{
|
||||
this._isCompleted = isCompleted;
|
||||
}
|
||||
public boolean getIsCompleted()
|
||||
{
|
||||
return this._isCompleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result returned by a dialog that was just ended.This will only be populated in certain
|
||||
* cases:
|
||||
* - The bot calls `dc.begin()` to start a new dialog and the dialog ends immediately.
|
||||
* - The bot calls `dc.continue()` and a dialog that was active ends.
|
||||
* In all cases where it's populated, [active](#active) will be `false`.
|
||||
*/
|
||||
HashMap<String, Object> _result;
|
||||
public HashMap<String, Object> getResult() {
|
||||
return _result;
|
||||
}
|
||||
public void setResult(HashMap<String, Object> result) {
|
||||
this._result = result;
|
||||
}
|
||||
}
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Result returned to the caller of one of the various stack manipulation methods and used to
|
||||
* return the result from a final call to `DialogContext.end()` to the bots logic.
|
||||
*/
|
||||
public class DialogCompletion
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* If 'true' the dialog is still active.
|
||||
*/
|
||||
boolean _isActive;
|
||||
public void setIsActive(boolean isActive) {
|
||||
this._isActive = isActive;
|
||||
}
|
||||
public boolean getIsActive() {
|
||||
return this._isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* If 'true' the dialog just completed and the final [result](#result) can be retrieved.
|
||||
*/
|
||||
boolean _isCompleted;
|
||||
public void setIsCompleted(boolean isCompleted)
|
||||
{
|
||||
this._isCompleted = isCompleted;
|
||||
}
|
||||
public boolean getIsCompleted()
|
||||
{
|
||||
return this._isCompleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result returned by a dialog that was just ended.This will only be populated in certain
|
||||
* cases:
|
||||
* - The bot calls `dc.begin()` to start a new dialog and the dialog ends immediately.
|
||||
* - The bot calls `dc.continue()` and a dialog that was active ends.
|
||||
* In all cases where it's populated, [active](#active) will be `false`.
|
||||
*/
|
||||
HashMap<String, Object> _result;
|
||||
public HashMap<String, Object> getResult() {
|
||||
return _result;
|
||||
}
|
||||
public void setResult(HashMap<String, Object> result) {
|
||||
this._result = result;
|
||||
}
|
||||
}
|
|
@ -1,50 +1,50 @@
|
|||
/*
|
||||
public class DialogContainer implements IDialogContinue
|
||||
|
||||
|
||||
{
|
||||
protected DialogSet Dialogs { get; set; }
|
||||
protected string DialogId { get; set; }
|
||||
|
||||
public DialogContainer(string dialogId, DialogSet dialogs = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dialogId))
|
||||
throw new ArgumentNullException(nameof(dialogId));
|
||||
|
||||
Dialogs dialogs = (dialogs != null) ? dialogs : new DialogSet();
|
||||
DialogId = dialogId;
|
||||
}
|
||||
|
||||
public async Task DialogBegin(DialogContext dc, IDictionary<string, object> dialogArgs = null)
|
||||
{
|
||||
if (dc == null)
|
||||
throw new ArgumentNullException(nameof(dc));
|
||||
|
||||
// Start the controls entry point dialog.
|
||||
IDictionary<string, object> result = null;
|
||||
var cdc = new DialogContext(this.Dialogs, dc.Context, dc.ActiveDialog.State, (r) => { result = r; });
|
||||
await cdc.Begin(DialogId, dialogArgs);
|
||||
// End if the controls dialog ends.
|
||||
if (cdc.ActiveDialog == null)
|
||||
{
|
||||
await dc.End(result);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DialogContinue(DialogContext dc)
|
||||
{
|
||||
if (dc == null)
|
||||
throw new ArgumentNullException(nameof(dc));
|
||||
|
||||
// Continue controls dialog stack.
|
||||
IDictionary<string, object> result = null;
|
||||
var cdc = new DialogContext(this.Dialogs, dc.Context, dc.ActiveDialog.State, (r) => { result = r; });
|
||||
await cdc.Continue();
|
||||
// End if the controls dialog ends.
|
||||
if (cdc.ActiveDialog == null)
|
||||
{
|
||||
await dc.End(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
public class DialogContainer implements IDialogContinue
|
||||
|
||||
|
||||
{
|
||||
protected DialogSet Dialogs { get; set; }
|
||||
protected string DialogId { get; set; }
|
||||
|
||||
public DialogContainer(string dialogId, DialogSet dialogs = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dialogId))
|
||||
throw new ArgumentNullException(nameof(dialogId));
|
||||
|
||||
Dialogs dialogs = (dialogs != null) ? dialogs : new DialogSet();
|
||||
DialogId = dialogId;
|
||||
}
|
||||
|
||||
public async Task DialogBegin(DialogContext dc, IDictionary<string, object> dialogArgs = null)
|
||||
{
|
||||
if (dc == null)
|
||||
throw new ArgumentNullException(nameof(dc));
|
||||
|
||||
// Start the controls entry point dialog.
|
||||
IDictionary<string, object> result = null;
|
||||
var cdc = new DialogContext(this.Dialogs, dc.Context, dc.ActiveDialog.State, (r) => { result = r; });
|
||||
await cdc.Begin(DialogId, dialogArgs);
|
||||
// End if the controls dialog ends.
|
||||
if (cdc.ActiveDialog == null)
|
||||
{
|
||||
await dc.End(result);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DialogContinue(DialogContext dc)
|
||||
{
|
||||
if (dc == null)
|
||||
throw new ArgumentNullException(nameof(dc));
|
||||
|
||||
// Continue controls dialog stack.
|
||||
IDictionary<string, object> result = null;
|
||||
var cdc = new DialogContext(this.Dialogs, dc.Context, dc.ActiveDialog.State, (r) => { result = r; });
|
||||
await cdc.Continue();
|
||||
// End if the controls dialog ends.
|
||||
if (cdc.ActiveDialog == null)
|
||||
{
|
||||
await dc.End(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -1,167 +1,167 @@
|
|||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Microsoft Bot Framework: http://botframework.com
|
||||
//
|
||||
// Bot Builder SDK GitHub:
|
||||
// https://github.com/Microsoft/BotBuilder
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// MIT License:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
/**
|
||||
* Encapsulates a method that represents the code to execute after a result is available.
|
||||
*
|
||||
* The result is often a message from the user.
|
||||
*
|
||||
* @param T The type of the result.
|
||||
* @param context The dialog context.
|
||||
* @param result The result.
|
||||
* @return A task that represents the code that will resume after the result is available.
|
||||
*/
|
||||
|
||||
/*
|
||||
public interface ResumeAfter
|
||||
{
|
||||
CompletableFuture invoke(DialogContext contenxt, Available)
|
||||
}
|
||||
|
||||
public delegate Task ResumeAfter<in T>(IDialogContext context, IAwaitable<T> result);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encapsulate a method that represents the code to start a dialog.
|
||||
* @param context The dialog context.
|
||||
* @return A task that represents the start code for a dialog.
|
||||
*/
|
||||
//public delegate Task StartAsync(IDialogContext context);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The context for the execution of a dialog's conversational process.
|
||||
*/
|
||||
// DAVETA: TODO
|
||||
// public interface DialogContext extends
|
||||
public interface DialogContext {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper methods.
|
||||
*/
|
||||
/*
|
||||
public static partial class Extensions
|
||||
{*/
|
||||
/**
|
||||
* Post a message to be sent to the user, using previous messages to establish a conversation context.
|
||||
*
|
||||
* If the locale parameter is not set, locale of the incoming message will be used for reply.
|
||||
*
|
||||
* @param botToUser Communication channel to use.
|
||||
* @param text The message text.
|
||||
* @param locale The locale of the text.
|
||||
* @return A task that represents the post operation.
|
||||
*/
|
||||
/*
|
||||
public static async Task PostAsync(this BotToUser botToUser, string text, string locale = null)
|
||||
{
|
||||
var message = botToUser.MakeMessage();
|
||||
message.Text = text;
|
||||
|
||||
if (!string.IsNullOrEmpty(locale))
|
||||
{
|
||||
message.Locale = locale;
|
||||
}
|
||||
|
||||
await botToUser.PostAsync(message);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Post a message and optional SSML to be sent to the user, using previous messages to establish a conversation context.
|
||||
*
|
||||
* If the locale parameter is not set, locale of the incoming message will be used for reply.
|
||||
*
|
||||
* @param botToUser Communication channel to use.
|
||||
* @param text The message text.
|
||||
* @param speak The SSML markup for text to speech.
|
||||
* @param options The options for the message.
|
||||
* @param locale The locale of the text.
|
||||
* @return A task that represents the post operation.
|
||||
*/
|
||||
/* public static async Task SayAsync(this BotToUser botToUser, string text, string speak = null, MessageOptions options = null, string locale = null)
|
||||
{
|
||||
var message = botToUser.MakeMessage();
|
||||
|
||||
message.Text = text;
|
||||
message.Speak = speak;
|
||||
|
||||
if (!string.IsNullOrEmpty(locale))
|
||||
{
|
||||
message.Locale = locale;
|
||||
}
|
||||
|
||||
if (options != null)
|
||||
{
|
||||
message.InputHint = options.InputHint;
|
||||
message.TextFormat = options.TextFormat;
|
||||
message.AttachmentLayout = options.AttachmentLayout;
|
||||
message.Attachments = options.Attachments;
|
||||
message.Entities = options.Entities;
|
||||
}
|
||||
|
||||
await botToUser.PostAsync(message);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Suspend the current dialog until the user has sent a message to the bot.
|
||||
* @param stack The dialog stack.
|
||||
* @param resume The method to resume when the message has been received.
|
||||
*/
|
||||
/*
|
||||
public static void Wait(this IDialogStack stack, ResumeAfter<MessageActivity> resume)
|
||||
{
|
||||
stack.Wait<MessageActivity>(resume);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Call a child dialog, add it to the top of the stack and post the message to the child dialog.
|
||||
* @param R The type of result expected from the child dialog.
|
||||
* @param stack The dialog stack.
|
||||
* @param child The child dialog.
|
||||
* @param resume The method to resume when the child dialog has completed.
|
||||
* @param message The message that will be posted to child dialog.
|
||||
* @return A task representing the Forward operation.
|
||||
*/
|
||||
/* public static async Task Forward<R>(this IDialogStack stack, IDialog<R> child, ResumeAfter<R> resume, MessageActivity message)
|
||||
{
|
||||
await stack.Forward<R, MessageActivity>(child, resume, message, token);
|
||||
}
|
||||
}*/
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
//
|
||||
// Microsoft Bot Framework: http://botframework.com
|
||||
//
|
||||
// Bot Builder SDK GitHub:
|
||||
// https://github.com/Microsoft/BotBuilder
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// MIT License:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
/**
|
||||
* Encapsulates a method that represents the code to execute after a result is available.
|
||||
*
|
||||
* The result is often a message from the user.
|
||||
*
|
||||
* @param T The type of the result.
|
||||
* @param context The dialog context.
|
||||
* @param result The result.
|
||||
* @return A task that represents the code that will resume after the result is available.
|
||||
*/
|
||||
|
||||
/*
|
||||
public interface ResumeAfter
|
||||
{
|
||||
CompletableFuture invoke(DialogContext contenxt, Available)
|
||||
}
|
||||
|
||||
public delegate Task ResumeAfter<in T>(IDialogContext context, IAwaitable<T> result);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encapsulate a method that represents the code to start a dialog.
|
||||
* @param context The dialog context.
|
||||
* @return A task that represents the start code for a dialog.
|
||||
*/
|
||||
//public delegate Task StartAsync(IDialogContext context);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The context for the execution of a dialog's conversational process.
|
||||
*/
|
||||
// DAVETA: TODO
|
||||
// public interface DialogContext extends
|
||||
public interface DialogContext {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper methods.
|
||||
*/
|
||||
/*
|
||||
public static partial class Extensions
|
||||
{*/
|
||||
/**
|
||||
* Post a message to be sent to the user, using previous messages to establish a conversation context.
|
||||
*
|
||||
* If the locale parameter is not set, locale of the incoming message will be used for reply.
|
||||
*
|
||||
* @param botToUser Communication channel to use.
|
||||
* @param text The message text.
|
||||
* @param locale The locale of the text.
|
||||
* @return A task that represents the post operation.
|
||||
*/
|
||||
/*
|
||||
public static async Task PostAsync(this BotToUser botToUser, string text, string locale = null)
|
||||
{
|
||||
var message = botToUser.MakeMessage();
|
||||
message.Text = text;
|
||||
|
||||
if (!string.IsNullOrEmpty(locale))
|
||||
{
|
||||
message.Locale = locale;
|
||||
}
|
||||
|
||||
await botToUser.PostAsync(message);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Post a message and optional SSML to be sent to the user, using previous messages to establish a conversation context.
|
||||
*
|
||||
* If the locale parameter is not set, locale of the incoming message will be used for reply.
|
||||
*
|
||||
* @param botToUser Communication channel to use.
|
||||
* @param text The message text.
|
||||
* @param speak The SSML markup for text to speech.
|
||||
* @param options The options for the message.
|
||||
* @param locale The locale of the text.
|
||||
* @return A task that represents the post operation.
|
||||
*/
|
||||
/* public static async Task SayAsync(this BotToUser botToUser, string text, string speak = null, MessageOptions options = null, string locale = null)
|
||||
{
|
||||
var message = botToUser.MakeMessage();
|
||||
|
||||
message.Text = text;
|
||||
message.Speak = speak;
|
||||
|
||||
if (!string.IsNullOrEmpty(locale))
|
||||
{
|
||||
message.Locale = locale;
|
||||
}
|
||||
|
||||
if (options != null)
|
||||
{
|
||||
message.InputHint = options.InputHint;
|
||||
message.TextFormat = options.TextFormat;
|
||||
message.AttachmentLayout = options.AttachmentLayout;
|
||||
message.Attachments = options.Attachments;
|
||||
message.Entities = options.Entities;
|
||||
}
|
||||
|
||||
await botToUser.PostAsync(message);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Suspend the current dialog until the user has sent a message to the bot.
|
||||
* @param stack The dialog stack.
|
||||
* @param resume The method to resume when the message has been received.
|
||||
*/
|
||||
/*
|
||||
public static void Wait(this IDialogStack stack, ResumeAfter<MessageActivity> resume)
|
||||
{
|
||||
stack.Wait<MessageActivity>(resume);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Call a child dialog, add it to the top of the stack and post the message to the child dialog.
|
||||
* @param R The type of result expected from the child dialog.
|
||||
* @param stack The dialog stack.
|
||||
* @param child The child dialog.
|
||||
* @param resume The method to resume when the child dialog has completed.
|
||||
* @param message The message that will be posted to child dialog.
|
||||
* @return A task representing the Forward operation.
|
||||
*/
|
||||
/* public static async Task Forward<R>(this IDialogStack stack, IDialog<R> child, ResumeAfter<R> resume, MessageActivity message)
|
||||
{
|
||||
await stack.Forward<R, MessageActivity>(child, resume, message, token);
|
||||
}
|
||||
}*/
|
|
@ -1,19 +1,19 @@
|
|||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
// TODO: daveta remove this - not sure where this came from
|
||||
/**
|
||||
* Interface for all Dialog objects that can be added to a `DialogSet`. The dialog should generally
|
||||
* be a singleton and added to a dialog set using `DialogSet.add()` at which point it will be
|
||||
* assigned a unique ID.
|
||||
*/
|
||||
public interface IDialog
|
||||
{
|
||||
/**
|
||||
* Method called when a new dialog has been pushed onto the stack and is being activated.
|
||||
* @param dc The dialog context for the current turn of conversation.
|
||||
* @param dialogArgs (Optional) arguments that were passed to the dialog during `begin()` call that started the instance.
|
||||
*/
|
||||
//CompleteableFuture DialogBegin(DialogContext dc, IDictionary<string, object> dialogArgs = null);
|
||||
//CompleteableFuture DialogBegin(DialogContext dc, HashMap<string, object> dialogArgs);
|
||||
//CompleteableFuture DialogBegin(DialogContext dc);
|
||||
}
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
// TODO: daveta remove this - not sure where this came from
|
||||
/**
|
||||
* Interface for all Dialog objects that can be added to a `DialogSet`. The dialog should generally
|
||||
* be a singleton and added to a dialog set using `DialogSet.add()` at which point it will be
|
||||
* assigned a unique ID.
|
||||
*/
|
||||
public interface IDialog
|
||||
{
|
||||
/**
|
||||
* Method called when a new dialog has been pushed onto the stack and is being activated.
|
||||
* @param dc The dialog context for the current turn of conversation.
|
||||
* @param dialogArgs (Optional) arguments that were passed to the dialog during `begin()` call that started the instance.
|
||||
*/
|
||||
//CompleteableFuture DialogBegin(DialogContext dc, IDictionary<string, object> dialogArgs = null);
|
||||
//CompleteableFuture DialogBegin(DialogContext dc, HashMap<string, object> dialogArgs);
|
||||
//CompleteableFuture DialogBegin(DialogContext dc);
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Interface Dialog objects that can be continued.
|
||||
*/
|
||||
public interface IDialogContinue extends IDialog
|
||||
{
|
||||
/**
|
||||
* Method called when an instance of the dialog is the "current" dialog and the
|
||||
* user replies with a new activity. The dialog will generally continue to receive the users
|
||||
* replies until it calls either `DialogSet.end()` or `DialogSet.begin()`.
|
||||
* If this method is NOT implemented then the dialog will automatically be ended when the user replies.
|
||||
* @param dc The dialog context for the current turn of conversation.
|
||||
*/
|
||||
CompletableFuture DialogContinue(DialogContext dc);
|
||||
}
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Interface Dialog objects that can be continued.
|
||||
*/
|
||||
public interface IDialogContinue extends IDialog
|
||||
{
|
||||
/**
|
||||
* Method called when an instance of the dialog is the "current" dialog and the
|
||||
* user replies with a new activity. The dialog will generally continue to receive the users
|
||||
* replies until it calls either `DialogSet.end()` or `DialogSet.begin()`.
|
||||
* If this method is NOT implemented then the dialog will automatically be ended when the user replies.
|
||||
* @param dc The dialog context for the current turn of conversation.
|
||||
*/
|
||||
CompletableFuture DialogContinue(DialogContext dc);
|
||||
}
|
|
@ -1,57 +1,57 @@
|
|||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
import com.microsoft.bot.schema.models.AttachmentLayoutTypes;
|
||||
import com.microsoft.bot.schema.models.TextFormatTypes;
|
||||
|
||||
/**
|
||||
* Optional message properties that can be sent {@link Extensions.SayAsync(BotToUser, String MessageOptions,)}
|
||||
*/
|
||||
public class MessageOptions
|
||||
{
|
||||
public MessageOptions()
|
||||
{
|
||||
this.setTextFormat(TextFormatTypes.MARKDOWN.toString());
|
||||
this.setAttachmentLayout(AttachmentLayoutTypes.LIST.toString());
|
||||
// this.Attachments = new ArrayList<Attachment>();
|
||||
// this.Entities = new ArrayList<Entity>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the bot is accepting, expecting, or ignoring input
|
||||
*/
|
||||
//public string InputHint { get; set; }
|
||||
|
||||
/**
|
||||
* Format of text fields [plain|markdown] Default:markdown
|
||||
*/
|
||||
String textFormat;
|
||||
public String getTextFormat() {
|
||||
return this.textFormat;
|
||||
}
|
||||
public void setTextFormat(String textFormat) {
|
||||
this.textFormat = textFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Hint for how to deal with multiple attachments: [list|carousel] Default:list
|
||||
*/
|
||||
String attachmentLayout;
|
||||
public String getAttachmentLayout() {
|
||||
return this.attachmentLayout;
|
||||
}
|
||||
public void setAttachmentLayout(String attachmentLayout) {
|
||||
this.attachmentLayout = attachmentLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachments
|
||||
*/
|
||||
//public IList<Attachment> Attachments { get; set; }
|
||||
|
||||
/**
|
||||
* Collection of Entity objects, each of which contains metadata about this activity. Each Entity object is typed.
|
||||
*/
|
||||
//public IList<Microsoft.Bot.Schema.Entity> Entities { get; set; }
|
||||
}
|
||||
package com.microsoft.bot.builder.dialogs;
|
||||
|
||||
import com.microsoft.bot.schema.models.AttachmentLayoutTypes;
|
||||
import com.microsoft.bot.schema.models.TextFormatTypes;
|
||||
|
||||
/**
|
||||
* Optional message properties that can be sent {@link Extensions.SayAsync(BotToUser, String MessageOptions,)}
|
||||
*/
|
||||
public class MessageOptions
|
||||
{
|
||||
public MessageOptions()
|
||||
{
|
||||
this.setTextFormat(TextFormatTypes.MARKDOWN.toString());
|
||||
this.setAttachmentLayout(AttachmentLayoutTypes.LIST.toString());
|
||||
// this.Attachments = new ArrayList<Attachment>();
|
||||
// this.Entities = new ArrayList<Entity>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the bot is accepting, expecting, or ignoring input
|
||||
*/
|
||||
//public string InputHint { get; set; }
|
||||
|
||||
/**
|
||||
* Format of text fields [plain|markdown] Default:markdown
|
||||
*/
|
||||
String textFormat;
|
||||
public String getTextFormat() {
|
||||
return this.textFormat;
|
||||
}
|
||||
public void setTextFormat(String textFormat) {
|
||||
this.textFormat = textFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Hint for how to deal with multiple attachments: [list|carousel] Default:list
|
||||
*/
|
||||
String attachmentLayout;
|
||||
public String getAttachmentLayout() {
|
||||
return this.attachmentLayout;
|
||||
}
|
||||
public void setAttachmentLayout(String attachmentLayout) {
|
||||
this.attachmentLayout = attachmentLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachments
|
||||
*/
|
||||
//public IList<Attachment> Attachments { get; set; }
|
||||
|
||||
/**
|
||||
* Collection of Entity objects, each of which contains metadata about this activity. Each Entity object is typed.
|
||||
*/
|
||||
//public IList<Microsoft.Bot.Schema.Entity> Entities { get; set; }
|
||||
}
|
|
@ -1,43 +1,43 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder.prompts;
|
||||
|
||||
import com.microsoft.bot.schema.models.CardAction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Choice
|
||||
{
|
||||
/**
|
||||
* Value to return when selected.
|
||||
*/
|
||||
String _value;
|
||||
public void setValue(String value) {
|
||||
this._value = value;
|
||||
}
|
||||
public String getValue() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) action to use when rendering the choice as a suggested action.
|
||||
*/
|
||||
CardAction _action;
|
||||
public CardAction getAction() {
|
||||
return this._action;
|
||||
}
|
||||
public void setAction(CardAction action) {
|
||||
this._action = action;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) list of synonyms to recognize in addition to the value.
|
||||
*/
|
||||
ArrayList<String> _synonyms;
|
||||
public ArrayList<String> getSynonyms() {
|
||||
return _synonyms;
|
||||
}
|
||||
public void setSynonyms(ArrayList<String> synonyms) {
|
||||
this._synonyms = synonyms;
|
||||
}
|
||||
}
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.bot.builder.prompts;
|
||||
|
||||
import com.microsoft.bot.schema.models.CardAction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Choice
|
||||
{
|
||||
/**
|
||||
* Value to return when selected.
|
||||
*/
|
||||
String _value;
|
||||
public void setValue(String value) {
|
||||
this._value = value;
|
||||
}
|
||||
public String getValue() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) action to use when rendering the choice as a suggested action.
|
||||
*/
|
||||
CardAction _action;
|
||||
public CardAction getAction() {
|
||||
return this._action;
|
||||
}
|
||||
public void setAction(CardAction action) {
|
||||
this._action = action;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) list of synonyms to recognize in addition to the value.
|
||||
*/
|
||||
ArrayList<String> _synonyms;
|
||||
public ArrayList<String> getSynonyms() {
|
||||
return _synonyms;
|
||||
}
|
||||
public void setSynonyms(ArrayList<String> synonyms) {
|
||||
this._synonyms = synonyms;
|
||||
}
|
||||
}
|
|
@ -1,25 +1,25 @@
|
|||
{
|
||||
"configuration": {
|
||||
"name": "Default",
|
||||
"appenders": {
|
||||
"Console": {
|
||||
"name": "Console-Appender",
|
||||
"target": "SYSTEM_OUT",
|
||||
"PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"}
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"logger": [
|
||||
{
|
||||
"name": "com.microsoft.bot.builder",
|
||||
"level": "debug",
|
||||
"appender-ref": [{"ref": "Console-Appender", "level": "debug"}]
|
||||
}
|
||||
],
|
||||
"root": {
|
||||
"level": "warn",
|
||||
"appender-ref": {"ref": "Console-Appender","level": "warn"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"configuration": {
|
||||
"name": "Default",
|
||||
"appenders": {
|
||||
"Console": {
|
||||
"name": "Console-Appender",
|
||||
"target": "SYSTEM_OUT",
|
||||
"PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"}
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"logger": [
|
||||
{
|
||||
"name": "com.microsoft.bot.builder",
|
||||
"level": "debug",
|
||||
"appender-ref": [{"ref": "Console-Appender", "level": "debug"}]
|
||||
}
|
||||
],
|
||||
"root": {
|
||||
"level": "warn",
|
||||
"appender-ref": {"ref": "Console-Appender","level": "warn"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
// This is a proxy for some previous tests using Action bindings
|
||||
@FunctionalInterface
|
||||
public interface ActionDel {
|
||||
void CallMe();
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
// This is a proxy for some previous tests using Action bindings
|
||||
@FunctionalInterface
|
||||
public interface ActionDel {
|
||||
void CallMe();
|
||||
}
|
|
@ -1,42 +1,42 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.*;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BotFrameworkAdapterTest {
|
||||
@Test
|
||||
public void AdapterSingleUse()
|
||||
{
|
||||
SimpleAdapter a = new SimpleAdapter();
|
||||
a.Use(new CallCountingMiddleware());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void AdapterUseChaining()
|
||||
{
|
||||
SimpleAdapter a = new SimpleAdapter();
|
||||
a.Use(new CallCountingMiddleware()).Use(new CallCountingMiddleware());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void PassResourceResponsesThrough() throws Exception {
|
||||
Consumer<Activity[]> validateResponse = (activities) -> {
|
||||
// no need to do anything.
|
||||
};
|
||||
|
||||
SimpleAdapter a = new SimpleAdapter(validateResponse);
|
||||
TurnContextImpl c = new TurnContextImpl(a, new ActivityImpl());
|
||||
|
||||
String activityId = UUID.randomUUID().toString();
|
||||
ActivityImpl activity = TestMessage.Message()
|
||||
.withId(activityId);
|
||||
|
||||
ResourceResponse resourceResponse = c.SendActivity(activity);
|
||||
Assert.assertTrue("Incorrect response Id returned", resourceResponse.id() == activityId);
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.*;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BotFrameworkAdapterTest {
|
||||
@Test
|
||||
public void AdapterSingleUse()
|
||||
{
|
||||
SimpleAdapter a = new SimpleAdapter();
|
||||
a.Use(new CallCountingMiddleware());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void AdapterUseChaining()
|
||||
{
|
||||
SimpleAdapter a = new SimpleAdapter();
|
||||
a.Use(new CallCountingMiddleware()).Use(new CallCountingMiddleware());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void PassResourceResponsesThrough() throws Exception {
|
||||
Consumer<Activity[]> validateResponse = (activities) -> {
|
||||
// no need to do anything.
|
||||
};
|
||||
|
||||
SimpleAdapter a = new SimpleAdapter(validateResponse);
|
||||
TurnContextImpl c = new TurnContextImpl(a, new ActivityImpl());
|
||||
|
||||
String activityId = UUID.randomUUID().toString();
|
||||
ActivityImpl activity = TestMessage.Message()
|
||||
.withId(activityId);
|
||||
|
||||
ResourceResponse resourceResponse = c.SendActivity(activity);
|
||||
Assert.assertTrue("Incorrect response Id returned", resourceResponse.id() == activityId);
|
||||
}
|
||||
}
|
|
@ -1,379 +1,379 @@
|
|||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.microsoft.bot.builder.adapters.TestAdapter;
|
||||
import com.microsoft.bot.builder.adapters.TestFlow;
|
||||
import com.microsoft.bot.connector.implementation.ConnectorClientImpl;
|
||||
import com.microsoft.bot.schema.models.ChannelAccount;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
import com.microsoft.rest.RestClient;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
// [TestClass]
|
||||
// [TestCategory("State Management")]
|
||||
public class BotStateTest {
|
||||
protected ConnectorClientImpl connector;
|
||||
protected ChannelAccount bot;
|
||||
protected ChannelAccount user;
|
||||
|
||||
|
||||
protected void initializeClients(RestClient restClient, String botId, String userId) {
|
||||
|
||||
connector = new ConnectorClientImpl(restClient);
|
||||
bot = new ChannelAccount().withId(botId);
|
||||
user = new ChannelAccount().withId(userId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void cleanUpResources() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_DoNOTRememberContextState() throws ExecutionException, InterruptedException {
|
||||
|
||||
TestAdapter adapter = new TestAdapter();
|
||||
|
||||
new TestFlow(adapter, (context) -> {
|
||||
TestPocoState obj = StateTurnContextExtensions.<TestPocoState>GetConversationState(context);
|
||||
Assert.assertNull("context.state should not exist", obj); }
|
||||
)
|
||||
.Send("set value")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void State_RememberIStoreItemUserState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new UserState<TestState>(new MemoryStorage(), TestState::new));
|
||||
|
||||
|
||||
Consumer<TurnContext> callback = (context) -> {
|
||||
System.out.print(String.format("State_RememberIStoreItemUserState CALLBACK called.."));
|
||||
System.out.flush();
|
||||
TestState userState = StateTurnContextExtensions.<TestState>GetUserState(context);
|
||||
Assert.assertNotNull("user state should exist", userState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
userState.withValue("test");
|
||||
try {
|
||||
((TurnContextImpl)context).SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(userState.value()));
|
||||
((TurnContextImpl)context).SendActivity(userState.value());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
new TestFlow(adapter, callback)
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_RememberPocoUserState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new UserState<TestPocoState>(new MemoryStorage(), TestPocoState::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TestPocoState userState = StateTurnContextExtensions.<TestPocoState>GetUserState(context);
|
||||
|
||||
Assert.assertNotNull("user state should exist", userState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
userState.setValue("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(userState.getValue()));
|
||||
context.SendActivity(userState.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void State_RememberIStoreItemConversationState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TestState>(new MemoryStorage(), TestState::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TestState conversationState = StateTurnContextExtensions.<TestState>GetConversationState(context);
|
||||
Assert.assertNotNull("state.conversation should exist", conversationState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversationState.withValue("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(conversationState.value()));
|
||||
context.SendActivity(conversationState.value());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void State_RememberPocoConversationState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TestPocoState>(new MemoryStorage(), TestPocoState::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TestPocoState conversationState = StateTurnContextExtensions.<TestPocoState>GetConversationState(context);
|
||||
Assert.assertNotNull("state.conversation should exist", conversationState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversationState.setValue("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(conversationState.getValue()));
|
||||
context.SendActivity(conversationState.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_CustomStateManagerTest() throws ExecutionException, InterruptedException {
|
||||
|
||||
String testGuid = UUID.randomUUID().toString();
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new CustomKeyState(new MemoryStorage()));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
CustomState customState = CustomKeyState.Get(context);
|
||||
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
customState.setCustomString(testGuid);
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(customState.getCustomString()));
|
||||
context.SendActivity(customState.getCustomString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", testGuid.toString())
|
||||
.StartTest();
|
||||
}
|
||||
@Test
|
||||
public void State_RoundTripTypedObjectwTrace() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TypedObject>(new MemoryStorage(), TypedObject::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): STARTING : %s", Thread.currentThread().getId(), context.getActivity().text()));
|
||||
System.out.flush();
|
||||
TypedObject conversation = StateTurnContextExtensions.<TypedObject>GetConversationState(context);
|
||||
Assert.assertNotNull("conversationstate should exist", conversation);
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Text is : %s", Thread.currentThread().getId(), context.getActivity().text()));
|
||||
System.out.flush();
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversation.withName("test");
|
||||
try {
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Send activity : %s", Thread.currentThread().getId(),
|
||||
"value saved"));
|
||||
System.out.flush();
|
||||
ResourceResponse response = context.SendActivity("value saved");
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Response Id: %s", Thread.currentThread().getId(),
|
||||
response.id()));
|
||||
System.out.flush();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Send activity : %s", Thread.currentThread().getId(),
|
||||
"TypedObject"));
|
||||
System.out.flush();
|
||||
context.SendActivity("TypedObject");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Turn("set value", "value saved", "Description", 50000)
|
||||
.Turn("get value", "TypedObject", "Description", 50000)
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void State_RoundTripTypedObject() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TypedObject>(new MemoryStorage(), TypedObject::new));
|
||||
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TypedObject conversation = StateTurnContextExtensions.<TypedObject>GetConversationState(context);
|
||||
Assert.assertNotNull("conversationstate should exist", conversation);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversation.withName("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
context.SendActivity("TypedObject");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "TypedObject")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_UseBotStateDirectly() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter();
|
||||
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
BotState botStateManager = new BotState<CustomState>(new MemoryStorage(), "BotState:com.microsoft.bot.builder.core.extensions.BotState<CustomState>",
|
||||
(ctx) -> String.format("botstate/%s/%s/com.microsoft.bot.builder.core.extensions.BotState<CustomState>",
|
||||
ctx.getActivity().channelId(), ctx.getActivity().conversation().id()), CustomState::new);
|
||||
|
||||
// read initial state object
|
||||
CustomState customState = null;
|
||||
try {
|
||||
customState = (CustomState) botStateManager.<CustomState>Read(context).join();
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail("Error reading custom state");
|
||||
}
|
||||
|
||||
// this should be a 'new CustomState' as nothing is currently stored in storage
|
||||
Assert.assertEquals(customState, new CustomState());
|
||||
|
||||
// amend property and write to storage
|
||||
customState.setCustomString("test");
|
||||
try {
|
||||
botStateManager.Write(context, customState).join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail("Could not write customstate");
|
||||
}
|
||||
|
||||
// set customState to null before reading from storage
|
||||
customState = null;
|
||||
try {
|
||||
customState = (CustomState) botStateManager.<CustomState>Read(context).join();
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail("Could not read customstate back");
|
||||
}
|
||||
|
||||
// check object read from value has the correct value for CustomString
|
||||
Assert.assertEquals(customState.getCustomString(), "test");
|
||||
}
|
||||
)
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.microsoft.bot.builder.adapters.TestAdapter;
|
||||
import com.microsoft.bot.builder.adapters.TestFlow;
|
||||
import com.microsoft.bot.connector.implementation.ConnectorClientImpl;
|
||||
import com.microsoft.bot.schema.models.ChannelAccount;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
import com.microsoft.rest.RestClient;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
// [TestClass]
|
||||
// [TestCategory("State Management")]
|
||||
public class BotStateTest {
|
||||
protected ConnectorClientImpl connector;
|
||||
protected ChannelAccount bot;
|
||||
protected ChannelAccount user;
|
||||
|
||||
|
||||
protected void initializeClients(RestClient restClient, String botId, String userId) {
|
||||
|
||||
connector = new ConnectorClientImpl(restClient);
|
||||
bot = new ChannelAccount().withId(botId);
|
||||
user = new ChannelAccount().withId(userId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void cleanUpResources() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_DoNOTRememberContextState() throws ExecutionException, InterruptedException {
|
||||
|
||||
TestAdapter adapter = new TestAdapter();
|
||||
|
||||
new TestFlow(adapter, (context) -> {
|
||||
TestPocoState obj = StateTurnContextExtensions.<TestPocoState>GetConversationState(context);
|
||||
Assert.assertNull("context.state should not exist", obj); }
|
||||
)
|
||||
.Send("set value")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void State_RememberIStoreItemUserState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new UserState<TestState>(new MemoryStorage(), TestState::new));
|
||||
|
||||
|
||||
Consumer<TurnContext> callback = (context) -> {
|
||||
System.out.print(String.format("State_RememberIStoreItemUserState CALLBACK called.."));
|
||||
System.out.flush();
|
||||
TestState userState = StateTurnContextExtensions.<TestState>GetUserState(context);
|
||||
Assert.assertNotNull("user state should exist", userState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
userState.withValue("test");
|
||||
try {
|
||||
((TurnContextImpl)context).SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(userState.value()));
|
||||
((TurnContextImpl)context).SendActivity(userState.value());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
new TestFlow(adapter, callback)
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_RememberPocoUserState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new UserState<TestPocoState>(new MemoryStorage(), TestPocoState::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TestPocoState userState = StateTurnContextExtensions.<TestPocoState>GetUserState(context);
|
||||
|
||||
Assert.assertNotNull("user state should exist", userState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
userState.setValue("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(userState.getValue()));
|
||||
context.SendActivity(userState.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void State_RememberIStoreItemConversationState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TestState>(new MemoryStorage(), TestState::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TestState conversationState = StateTurnContextExtensions.<TestState>GetConversationState(context);
|
||||
Assert.assertNotNull("state.conversation should exist", conversationState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversationState.withValue("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(conversationState.value()));
|
||||
context.SendActivity(conversationState.value());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void State_RememberPocoConversationState() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TestPocoState>(new MemoryStorage(), TestPocoState::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TestPocoState conversationState = StateTurnContextExtensions.<TestPocoState>GetConversationState(context);
|
||||
Assert.assertNotNull("state.conversation should exist", conversationState);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversationState.setValue("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(conversationState.getValue()));
|
||||
context.SendActivity(conversationState.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "test")
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_CustomStateManagerTest() throws ExecutionException, InterruptedException {
|
||||
|
||||
String testGuid = UUID.randomUUID().toString();
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new CustomKeyState(new MemoryStorage()));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
CustomState customState = CustomKeyState.Get(context);
|
||||
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
customState.setCustomString(testGuid);
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
Assert.assertFalse(StringUtils.isBlank(customState.getCustomString()));
|
||||
context.SendActivity(customState.getCustomString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", testGuid.toString())
|
||||
.StartTest();
|
||||
}
|
||||
@Test
|
||||
public void State_RoundTripTypedObjectwTrace() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TypedObject>(new MemoryStorage(), TypedObject::new));
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): STARTING : %s", Thread.currentThread().getId(), context.getActivity().text()));
|
||||
System.out.flush();
|
||||
TypedObject conversation = StateTurnContextExtensions.<TypedObject>GetConversationState(context);
|
||||
Assert.assertNotNull("conversationstate should exist", conversation);
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Text is : %s", Thread.currentThread().getId(), context.getActivity().text()));
|
||||
System.out.flush();
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversation.withName("test");
|
||||
try {
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Send activity : %s", Thread.currentThread().getId(),
|
||||
"value saved"));
|
||||
System.out.flush();
|
||||
ResourceResponse response = context.SendActivity("value saved");
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Response Id: %s", Thread.currentThread().getId(),
|
||||
response.id()));
|
||||
System.out.flush();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
System.out.println(String.format(">>Test Callback(tid:%s): Send activity : %s", Thread.currentThread().getId(),
|
||||
"TypedObject"));
|
||||
System.out.flush();
|
||||
context.SendActivity("TypedObject");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Turn("set value", "value saved", "Description", 50000)
|
||||
.Turn("get value", "TypedObject", "Description", 50000)
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void State_RoundTripTypedObject() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new ConversationState<TypedObject>(new MemoryStorage(), TypedObject::new));
|
||||
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
TypedObject conversation = StateTurnContextExtensions.<TypedObject>GetConversationState(context);
|
||||
Assert.assertNotNull("conversationstate should exist", conversation);
|
||||
switch (context.getActivity().text()) {
|
||||
case "set value":
|
||||
conversation.withName("test");
|
||||
try {
|
||||
context.SendActivity("value saved");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - set value"));
|
||||
}
|
||||
break;
|
||||
case "get value":
|
||||
try {
|
||||
context.SendActivity("TypedObject");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(String.format("Error sending activity! - get value"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
.Test("set value", "value saved")
|
||||
.Test("get value", "TypedObject")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void State_UseBotStateDirectly() throws ExecutionException, InterruptedException {
|
||||
TestAdapter adapter = new TestAdapter();
|
||||
|
||||
new TestFlow(adapter,
|
||||
(context) ->
|
||||
{
|
||||
BotState botStateManager = new BotState<CustomState>(new MemoryStorage(), "BotState:com.microsoft.bot.builder.core.extensions.BotState<CustomState>",
|
||||
(ctx) -> String.format("botstate/%s/%s/com.microsoft.bot.builder.core.extensions.BotState<CustomState>",
|
||||
ctx.getActivity().channelId(), ctx.getActivity().conversation().id()), CustomState::new);
|
||||
|
||||
// read initial state object
|
||||
CustomState customState = null;
|
||||
try {
|
||||
customState = (CustomState) botStateManager.<CustomState>Read(context).join();
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail("Error reading custom state");
|
||||
}
|
||||
|
||||
// this should be a 'new CustomState' as nothing is currently stored in storage
|
||||
Assert.assertEquals(customState, new CustomState());
|
||||
|
||||
// amend property and write to storage
|
||||
customState.setCustomString("test");
|
||||
try {
|
||||
botStateManager.Write(context, customState).join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail("Could not write customstate");
|
||||
}
|
||||
|
||||
// set customState to null before reading from storage
|
||||
customState = null;
|
||||
try {
|
||||
customState = (CustomState) botStateManager.<CustomState>Read(context).join();
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail("Could not read customstate back");
|
||||
}
|
||||
|
||||
// check object read from value has the correct value for CustomString
|
||||
Assert.assertEquals(customState.getCustomString(), "test");
|
||||
}
|
||||
)
|
||||
.StartTest();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,28 +1,28 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
public class CallCountingMiddleware implements Middleware {
|
||||
private int calls = 0;
|
||||
|
||||
public int calls() {
|
||||
return this.calls;
|
||||
}
|
||||
|
||||
public CallCountingMiddleware withCalls(int calls) {
|
||||
this.calls = calls;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
this.calls++;
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("CallCountingMiddleWare: %s", e.toString()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class CallCountingMiddleware implements Middleware {
|
||||
private int calls = 0;
|
||||
|
||||
public int calls() {
|
||||
return this.calls;
|
||||
}
|
||||
|
||||
public CallCountingMiddleware withCalls(int calls) {
|
||||
this.calls = calls;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
this.calls++;
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("CallCountingMiddleWare: %s", e.toString()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
public class CallMeMiddlware implements Middleware {
|
||||
private ActionDel callMe;
|
||||
|
||||
public CallMeMiddlware(ActionDel callme) {
|
||||
this.callMe = callme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
|
||||
this.callMe.CallMe();
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class CallMeMiddlware implements Middleware {
|
||||
private ActionDel callMe;
|
||||
|
||||
public CallMeMiddlware(ActionDel callme) {
|
||||
this.callMe = callme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
|
||||
this.callMe.CallMe();
|
||||
try {
|
||||
next.next();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +1,109 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.adapters.TestAdapter;
|
||||
import com.microsoft.bot.builder.adapters.TestFlow;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class CatchException_MiddlewareTest {
|
||||
|
||||
@Test
|
||||
public void CatchException_TestMiddleware_TestStackedErrorMiddleware() throws ExecutionException, InterruptedException {
|
||||
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new CatchExceptionMiddleware<Exception>(new CallOnException() {
|
||||
@Override
|
||||
public <T> CompletableFuture apply(TurnContext context, T t) throws Exception {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
Activity activity = context.getActivity();
|
||||
if (activity instanceof ActivityImpl) {
|
||||
try {
|
||||
context.SendActivity(((ActivityImpl) activity).CreateReply(t.toString()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("CatchException_TestMiddleware_TestStackedErrorMiddleware:SendActivity failed %s", e.toString()));
|
||||
}
|
||||
} else
|
||||
Assert.assertTrue("Test was built for ActivityImpl", false);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}, Exception.class))
|
||||
// Add middleware to catch NullReferenceExceptions before throwing up to the general exception instance
|
||||
.Use(new CatchExceptionMiddleware<NullPointerException>(new CallOnException() {
|
||||
@Override
|
||||
public <T> CompletableFuture apply(TurnContext context, T t) throws Exception {
|
||||
context.SendActivity("Sorry - Null Reference Exception");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}, NullPointerException.class));
|
||||
|
||||
|
||||
new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
if (context.getActivity().text() == "foo") {
|
||||
try {
|
||||
context.SendActivity(context.getActivity().text());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (context.getActivity().text() == "UnsupportedOperationException") {
|
||||
throw new UnsupportedOperationException("Test");
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
.Send("foo")
|
||||
.AssertReply("foo", "passthrough")
|
||||
.Send("UnsupportedOperationException")
|
||||
.AssertReply("Test")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
/* @Test
|
||||
// [TestCategory("Middleware")]
|
||||
public void CatchException_TestMiddleware_SpecificExceptionType()
|
||||
{
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new CatchExceptionMiddleware<Exception>((context, exception) =>
|
||||
{
|
||||
context.SendActivity("Generic Exception Caught");
|
||||
return CompletableFuture.CompletedTask;
|
||||
}))
|
||||
.Use(new CatchExceptionMiddleware<NullReferenceException>((context, exception) =>
|
||||
{
|
||||
context.SendActivity(exception.Message);
|
||||
return CompletableFuture.CompletedTask;
|
||||
}));
|
||||
|
||||
|
||||
await new TestFlow(adapter, (context) =>
|
||||
{
|
||||
if (context.Activity.AsMessageActivity().Text == "foo")
|
||||
{
|
||||
context.SendActivity(context.Activity.AsMessageActivity().Text);
|
||||
}
|
||||
|
||||
if (context.Activity.AsMessageActivity().Text == "NullReferenceException")
|
||||
{
|
||||
throw new NullReferenceException("Test");
|
||||
}
|
||||
|
||||
return CompletableFuture.CompletedTask;
|
||||
})
|
||||
.Send("foo")
|
||||
.AssertReply("foo", "passthrough")
|
||||
.Send("NullReferenceException")
|
||||
.AssertReply("Test")
|
||||
.StartTest();
|
||||
}*/
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.adapters.TestAdapter;
|
||||
import com.microsoft.bot.builder.adapters.TestFlow;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class CatchException_MiddlewareTest {
|
||||
|
||||
@Test
|
||||
public void CatchException_TestMiddleware_TestStackedErrorMiddleware() throws ExecutionException, InterruptedException {
|
||||
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new CatchExceptionMiddleware<Exception>(new CallOnException() {
|
||||
@Override
|
||||
public <T> CompletableFuture apply(TurnContext context, T t) throws Exception {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
Activity activity = context.getActivity();
|
||||
if (activity instanceof ActivityImpl) {
|
||||
try {
|
||||
context.SendActivity(((ActivityImpl) activity).CreateReply(t.toString()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("CatchException_TestMiddleware_TestStackedErrorMiddleware:SendActivity failed %s", e.toString()));
|
||||
}
|
||||
} else
|
||||
Assert.assertTrue("Test was built for ActivityImpl", false);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}, Exception.class))
|
||||
// Add middleware to catch NullReferenceExceptions before throwing up to the general exception instance
|
||||
.Use(new CatchExceptionMiddleware<NullPointerException>(new CallOnException() {
|
||||
@Override
|
||||
public <T> CompletableFuture apply(TurnContext context, T t) throws Exception {
|
||||
context.SendActivity("Sorry - Null Reference Exception");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}, NullPointerException.class));
|
||||
|
||||
|
||||
new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
if (context.getActivity().text() == "foo") {
|
||||
try {
|
||||
context.SendActivity(context.getActivity().text());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (context.getActivity().text() == "UnsupportedOperationException") {
|
||||
throw new UnsupportedOperationException("Test");
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
.Send("foo")
|
||||
.AssertReply("foo", "passthrough")
|
||||
.Send("UnsupportedOperationException")
|
||||
.AssertReply("Test")
|
||||
.StartTest();
|
||||
|
||||
}
|
||||
|
||||
/* @Test
|
||||
// [TestCategory("Middleware")]
|
||||
public void CatchException_TestMiddleware_SpecificExceptionType()
|
||||
{
|
||||
TestAdapter adapter = new TestAdapter()
|
||||
.Use(new CatchExceptionMiddleware<Exception>((context, exception) =>
|
||||
{
|
||||
context.SendActivity("Generic Exception Caught");
|
||||
return CompletableFuture.CompletedTask;
|
||||
}))
|
||||
.Use(new CatchExceptionMiddleware<NullReferenceException>((context, exception) =>
|
||||
{
|
||||
context.SendActivity(exception.Message);
|
||||
return CompletableFuture.CompletedTask;
|
||||
}));
|
||||
|
||||
|
||||
await new TestFlow(adapter, (context) =>
|
||||
{
|
||||
if (context.Activity.AsMessageActivity().Text == "foo")
|
||||
{
|
||||
context.SendActivity(context.Activity.AsMessageActivity().Text);
|
||||
}
|
||||
|
||||
if (context.Activity.AsMessageActivity().Text == "NullReferenceException")
|
||||
{
|
||||
throw new NullReferenceException("Test");
|
||||
}
|
||||
|
||||
return CompletableFuture.CompletedTask;
|
||||
})
|
||||
.Send("foo")
|
||||
.AssertReply("foo", "passthrough")
|
||||
.Send("NullReferenceException")
|
||||
.AssertReply("Test")
|
||||
.StartTest();
|
||||
}*/
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
public class CustomKeyState extends BotState<CustomState> {
|
||||
public static final String PropertyName = "Microsoft.Bot.Builder.Tests.CustomKeyState";
|
||||
|
||||
public CustomKeyState(Storage storage) {
|
||||
super(storage, CustomKeyState.PropertyName, (context) -> "CustomKey", CustomState::new);
|
||||
}
|
||||
|
||||
public static CustomState Get(TurnContext context) {
|
||||
return context.getServices().<CustomState>Get(PropertyName);
|
||||
}
|
||||
}
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
public class CustomKeyState extends BotState<CustomState> {
|
||||
public static final String PropertyName = "Microsoft.Bot.Builder.Tests.CustomKeyState";
|
||||
|
||||
public CustomKeyState(Storage storage) {
|
||||
super(storage, CustomKeyState.PropertyName, (context) -> "CustomKey", CustomState::new);
|
||||
}
|
||||
|
||||
public static CustomState Get(TurnContext context) {
|
||||
return context.getServices().<CustomState>Get(PropertyName);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +1,29 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.StoreItem;
|
||||
|
||||
public class CustomState implements StoreItem
|
||||
|
||||
{
|
||||
private String _customString;
|
||||
|
||||
public String getCustomString() {
|
||||
return _customString;
|
||||
}
|
||||
|
||||
public void setCustomString(String customString) {
|
||||
this._customString = customString;
|
||||
}
|
||||
|
||||
private String _eTag;
|
||||
|
||||
public String geteTag()
|
||||
|
||||
{
|
||||
return _eTag;
|
||||
}
|
||||
|
||||
public void seteTag(String eTag) {
|
||||
this._eTag = eTag;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.StoreItem;
|
||||
|
||||
public class CustomState implements StoreItem
|
||||
|
||||
{
|
||||
private String _customString;
|
||||
|
||||
public String getCustomString() {
|
||||
return _customString;
|
||||
}
|
||||
|
||||
public void setCustomString(String customString) {
|
||||
this._customString = customString;
|
||||
}
|
||||
|
||||
private String _eTag;
|
||||
|
||||
public String geteTag()
|
||||
|
||||
{
|
||||
return _eTag;
|
||||
}
|
||||
|
||||
public void seteTag(String eTag) {
|
||||
this._eTag = eTag;
|
||||
}
|
||||
}
|
|
@ -1,129 +1,129 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
|
||||
/**
|
||||
* Models IStorage around a dictionary
|
||||
*/
|
||||
public class DictionaryStorage implements Storage {
|
||||
private static ObjectMapper objectMapper;
|
||||
|
||||
// TODO: Object needs to be defined
|
||||
private final Map<String, Object> memory;
|
||||
private final Object syncroot = new Object();
|
||||
private int _eTag = 0;
|
||||
private final String typeNameForNonEntity = "__type_name_";
|
||||
|
||||
public DictionaryStorage() {
|
||||
this(null);
|
||||
}
|
||||
public DictionaryStorage(Map<String, Object> dictionary ) {
|
||||
DictionaryStorage.objectMapper = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.findAndRegisterModules();
|
||||
this.memory = (dictionary != null) ? dictionary : new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
public CompletableFuture Delete(String[] keys) {
|
||||
synchronized (this.syncroot) {
|
||||
for (String key : keys) {
|
||||
Object o = this.memory.get(key);
|
||||
this.memory.remove(o);
|
||||
}
|
||||
}
|
||||
return completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Map<String, ?>> Read(String[] keys) throws JsonProcessingException {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Map<String, Object> storeItems = new HashMap<String, Object>(keys.length);
|
||||
synchronized (this.syncroot) {
|
||||
for (String key : keys) {
|
||||
if (this.memory.containsKey(key)) {
|
||||
Object state = this.memory.get(key);
|
||||
if (state != null) {
|
||||
try {
|
||||
if (!(state instanceof JsonNode))
|
||||
throw new RuntimeException("DictionaryRead failed: entry not JsonNode");
|
||||
JsonNode stateNode = (JsonNode) state;
|
||||
// Check if type info is set for the class
|
||||
if (!(stateNode.hasNonNull(this.typeNameForNonEntity))) {
|
||||
throw new RuntimeException(String.format("DictionaryRead failed: Type info not present"));
|
||||
}
|
||||
String clsName = stateNode.get(this.typeNameForNonEntity).textValue();
|
||||
|
||||
// Load the class info
|
||||
Class<?> cls;
|
||||
try {
|
||||
cls = Class.forName(clsName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("DictionaryRead failed: Could not load class %s", clsName));
|
||||
}
|
||||
|
||||
// Populate dictionary
|
||||
storeItems.put(key,DictionaryStorage.objectMapper.treeToValue(stateNode, cls ));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("DictionaryRead failed: %s", e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return storeItems;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture Write(Map<String, ?> changes) throws Exception {
|
||||
synchronized (this.syncroot) {
|
||||
for (Map.Entry change : changes.entrySet()) {
|
||||
Object newValue = change.getValue();
|
||||
|
||||
String oldStateETag = null; // default(string);
|
||||
if (this.memory.containsValue(change.getKey())) {
|
||||
Map oldState = (Map) this.memory.get(change.getKey());
|
||||
if (oldState.containsValue("eTag")) {
|
||||
Map.Entry eTagToken = (Map.Entry) oldState.get("eTag");
|
||||
oldStateETag = (String) eTagToken.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
// Dictionary stores Key:JsonNode (with type information held within the JsonNode)
|
||||
JsonNode newState = DictionaryStorage.objectMapper.valueToTree(newValue);
|
||||
((ObjectNode)newState).put(this.typeNameForNonEntity, newValue.getClass().getTypeName());
|
||||
|
||||
// Set ETag if applicable
|
||||
if (newValue instanceof StoreItem) {
|
||||
StoreItem newStoreItem = (StoreItem) newValue;
|
||||
if(oldStateETag != null && newStoreItem.geteTag() != "*" &&
|
||||
newStoreItem.geteTag() != oldStateETag) {
|
||||
throw new Exception(String.format("Etag conflict.\r\n\r\nOriginal: %s\r\nCurrent: %s",
|
||||
newStoreItem.geteTag(), oldStateETag));
|
||||
}
|
||||
Integer newTag = _eTag++;
|
||||
((ObjectNode)newState).put("eTag", newTag.toString());
|
||||
}
|
||||
|
||||
this.memory.put((String)change.getKey(), newState);
|
||||
}
|
||||
}
|
||||
return completedFuture(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
|
||||
/**
|
||||
* Models IStorage around a dictionary
|
||||
*/
|
||||
public class DictionaryStorage implements Storage {
|
||||
private static ObjectMapper objectMapper;
|
||||
|
||||
// TODO: Object needs to be defined
|
||||
private final Map<String, Object> memory;
|
||||
private final Object syncroot = new Object();
|
||||
private int _eTag = 0;
|
||||
private final String typeNameForNonEntity = "__type_name_";
|
||||
|
||||
public DictionaryStorage() {
|
||||
this(null);
|
||||
}
|
||||
public DictionaryStorage(Map<String, Object> dictionary ) {
|
||||
DictionaryStorage.objectMapper = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.findAndRegisterModules();
|
||||
this.memory = (dictionary != null) ? dictionary : new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
public CompletableFuture Delete(String[] keys) {
|
||||
synchronized (this.syncroot) {
|
||||
for (String key : keys) {
|
||||
Object o = this.memory.get(key);
|
||||
this.memory.remove(o);
|
||||
}
|
||||
}
|
||||
return completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Map<String, ?>> Read(String[] keys) throws JsonProcessingException {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
Map<String, Object> storeItems = new HashMap<String, Object>(keys.length);
|
||||
synchronized (this.syncroot) {
|
||||
for (String key : keys) {
|
||||
if (this.memory.containsKey(key)) {
|
||||
Object state = this.memory.get(key);
|
||||
if (state != null) {
|
||||
try {
|
||||
if (!(state instanceof JsonNode))
|
||||
throw new RuntimeException("DictionaryRead failed: entry not JsonNode");
|
||||
JsonNode stateNode = (JsonNode) state;
|
||||
// Check if type info is set for the class
|
||||
if (!(stateNode.hasNonNull(this.typeNameForNonEntity))) {
|
||||
throw new RuntimeException(String.format("DictionaryRead failed: Type info not present"));
|
||||
}
|
||||
String clsName = stateNode.get(this.typeNameForNonEntity).textValue();
|
||||
|
||||
// Load the class info
|
||||
Class<?> cls;
|
||||
try {
|
||||
cls = Class.forName(clsName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("DictionaryRead failed: Could not load class %s", clsName));
|
||||
}
|
||||
|
||||
// Populate dictionary
|
||||
storeItems.put(key,DictionaryStorage.objectMapper.treeToValue(stateNode, cls ));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("DictionaryRead failed: %s", e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return storeItems;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture Write(Map<String, ?> changes) throws Exception {
|
||||
synchronized (this.syncroot) {
|
||||
for (Map.Entry change : changes.entrySet()) {
|
||||
Object newValue = change.getValue();
|
||||
|
||||
String oldStateETag = null; // default(string);
|
||||
if (this.memory.containsValue(change.getKey())) {
|
||||
Map oldState = (Map) this.memory.get(change.getKey());
|
||||
if (oldState.containsValue("eTag")) {
|
||||
Map.Entry eTagToken = (Map.Entry) oldState.get("eTag");
|
||||
oldStateETag = (String) eTagToken.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
// Dictionary stores Key:JsonNode (with type information held within the JsonNode)
|
||||
JsonNode newState = DictionaryStorage.objectMapper.valueToTree(newValue);
|
||||
((ObjectNode)newState).put(this.typeNameForNonEntity, newValue.getClass().getTypeName());
|
||||
|
||||
// Set ETag if applicable
|
||||
if (newValue instanceof StoreItem) {
|
||||
StoreItem newStoreItem = (StoreItem) newValue;
|
||||
if(oldStateETag != null && newStoreItem.geteTag() != "*" &&
|
||||
newStoreItem.geteTag() != oldStateETag) {
|
||||
throw new Exception(String.format("Etag conflict.\r\n\r\nOriginal: %s\r\nCurrent: %s",
|
||||
newStoreItem.geteTag(), oldStateETag));
|
||||
}
|
||||
Integer newTag = _eTag++;
|
||||
((ObjectNode)newState).put("eTag", newTag.toString());
|
||||
}
|
||||
|
||||
this.memory.put((String)change.getKey(), newState);
|
||||
}
|
||||
}
|
||||
return completedFuture(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
public class DoNotCallNextMiddleware implements Middleware {
|
||||
private final ActionDel _callMe;
|
||||
|
||||
public DoNotCallNextMiddleware(ActionDel callMe) {
|
||||
_callMe = callMe;
|
||||
}
|
||||
|
||||
public void OnTurn(TurnContext context, NextDelegate next) {
|
||||
_callMe.CallMe();
|
||||
// DO NOT call NEXT
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class DoNotCallNextMiddleware implements Middleware {
|
||||
private final ActionDel _callMe;
|
||||
|
||||
public DoNotCallNextMiddleware(ActionDel callMe) {
|
||||
_callMe = callMe;
|
||||
}
|
||||
|
||||
public void OnTurn(TurnContext context, NextDelegate next) {
|
||||
_callMe.CallMe();
|
||||
// DO NOT call NEXT
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.DictionaryStorage;
|
||||
|
||||
/**
|
||||
* RamStorage stores data in volative dictionary
|
||||
*/
|
||||
public class MemoryStorage extends DictionaryStorage {
|
||||
|
||||
public MemoryStorage() {
|
||||
super(null);
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.DictionaryStorage;
|
||||
|
||||
/**
|
||||
* RamStorage stores data in volative dictionary
|
||||
*/
|
||||
public class MemoryStorage extends DictionaryStorage {
|
||||
|
||||
public MemoryStorage() {
|
||||
super(null);
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,90 +1,90 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SimpleAdapter extends BotAdapter {
|
||||
private Consumer<Activity[]> callOnSend = null;
|
||||
private Consumer<Activity> callOnUpdate = null;
|
||||
private Consumer<ConversationReference> callOnDelete = null;
|
||||
|
||||
// Callback Function but doesn't need to be. Avoid java legacy type erasure
|
||||
public SimpleAdapter(Consumer<Activity[]> callOnSend) {
|
||||
this(callOnSend, null, null);
|
||||
}
|
||||
|
||||
public SimpleAdapter(Consumer<Activity[]> callOnSend, Consumer<Activity> callOnUpdate) {
|
||||
this(callOnSend, callOnUpdate, null);
|
||||
}
|
||||
|
||||
public SimpleAdapter(Consumer<Activity[]> callOnSend, Consumer<Activity> callOnUpdate, Consumer<ConversationReference> callOnDelete) {
|
||||
this.callOnSend = callOnSend;
|
||||
this.callOnUpdate = callOnUpdate;
|
||||
this.callOnDelete = callOnDelete;
|
||||
}
|
||||
|
||||
public SimpleAdapter() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceResponse[] SendActivities(TurnContext context, Activity[] activities) throws InterruptedException {
|
||||
Assert.assertNotNull("SimpleAdapter.deleteActivity: missing reference", activities);
|
||||
Assert.assertTrue("SimpleAdapter.sendActivities: empty activities array.", activities.length > 0);
|
||||
|
||||
if (this.callOnSend != null)
|
||||
this.callOnSend.accept(activities);
|
||||
|
||||
List<ResourceResponse> responses = new ArrayList<ResourceResponse>();
|
||||
for (Activity activity : activities) {
|
||||
responses.add(new ResourceResponse().withId(activity.id()));
|
||||
}
|
||||
ResourceResponse[] result = new ResourceResponse[responses.size()];
|
||||
return responses.toArray(result);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceResponse UpdateActivity(TurnContext context, Activity activity) {
|
||||
|
||||
Assert.assertNotNull("SimpleAdapter.updateActivity: missing activity", activity);
|
||||
if (this.callOnUpdate != null)
|
||||
this.callOnUpdate.accept(activity);
|
||||
return new ResourceResponse()
|
||||
.withId(activity.id());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DeleteActivity(TurnContext context, ConversationReference reference) throws ExecutionException, InterruptedException {
|
||||
Assert.assertNotNull("SimpleAdapter.deleteActivity: missing reference", reference);
|
||||
if (callOnDelete != null)
|
||||
this.callOnDelete.accept(reference);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void ProcessRequest(ActivityImpl activty, Consumer<TurnContext> callback) throws Exception {
|
||||
|
||||
try (TurnContextImpl ctx = new TurnContextImpl(this, activty)) {
|
||||
this.RunPipeline(ctx, callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Error running pipeline: %s", e.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
import com.microsoft.bot.schema.models.ResourceResponse;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SimpleAdapter extends BotAdapter {
|
||||
private Consumer<Activity[]> callOnSend = null;
|
||||
private Consumer<Activity> callOnUpdate = null;
|
||||
private Consumer<ConversationReference> callOnDelete = null;
|
||||
|
||||
// Callback Function but doesn't need to be. Avoid java legacy type erasure
|
||||
public SimpleAdapter(Consumer<Activity[]> callOnSend) {
|
||||
this(callOnSend, null, null);
|
||||
}
|
||||
|
||||
public SimpleAdapter(Consumer<Activity[]> callOnSend, Consumer<Activity> callOnUpdate) {
|
||||
this(callOnSend, callOnUpdate, null);
|
||||
}
|
||||
|
||||
public SimpleAdapter(Consumer<Activity[]> callOnSend, Consumer<Activity> callOnUpdate, Consumer<ConversationReference> callOnDelete) {
|
||||
this.callOnSend = callOnSend;
|
||||
this.callOnUpdate = callOnUpdate;
|
||||
this.callOnDelete = callOnDelete;
|
||||
}
|
||||
|
||||
public SimpleAdapter() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceResponse[] SendActivities(TurnContext context, Activity[] activities) throws InterruptedException {
|
||||
Assert.assertNotNull("SimpleAdapter.deleteActivity: missing reference", activities);
|
||||
Assert.assertTrue("SimpleAdapter.sendActivities: empty activities array.", activities.length > 0);
|
||||
|
||||
if (this.callOnSend != null)
|
||||
this.callOnSend.accept(activities);
|
||||
|
||||
List<ResourceResponse> responses = new ArrayList<ResourceResponse>();
|
||||
for (Activity activity : activities) {
|
||||
responses.add(new ResourceResponse().withId(activity.id()));
|
||||
}
|
||||
ResourceResponse[] result = new ResourceResponse[responses.size()];
|
||||
return responses.toArray(result);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceResponse UpdateActivity(TurnContext context, Activity activity) {
|
||||
|
||||
Assert.assertNotNull("SimpleAdapter.updateActivity: missing activity", activity);
|
||||
if (this.callOnUpdate != null)
|
||||
this.callOnUpdate.accept(activity);
|
||||
return new ResourceResponse()
|
||||
.withId(activity.id());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DeleteActivity(TurnContext context, ConversationReference reference) throws ExecutionException, InterruptedException {
|
||||
Assert.assertNotNull("SimpleAdapter.deleteActivity: missing reference", reference);
|
||||
if (callOnDelete != null)
|
||||
this.callOnDelete.accept(reference);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void ProcessRequest(ActivityImpl activty, Consumer<TurnContext> callback) throws Exception {
|
||||
|
||||
try (TurnContextImpl ctx = new TurnContextImpl(this, activty)) {
|
||||
this.RunPipeline(ctx, callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Error running pipeline: %s", e.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class StateSettings
|
||||
{
|
||||
private boolean lastWriterWins = true;
|
||||
public boolean getLastWriterWins() {
|
||||
return this.lastWriterWins;
|
||||
}
|
||||
public void setLast(boolean lastWriterWins) {
|
||||
this.lastWriterWins = lastWriterWins;
|
||||
}
|
||||
}
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class StateSettings
|
||||
{
|
||||
private boolean lastWriterWins = true;
|
||||
public boolean getLastWriterWins() {
|
||||
return this.lastWriterWins;
|
||||
}
|
||||
public void setLast(boolean lastWriterWins) {
|
||||
this.lastWriterWins = lastWriterWins;
|
||||
}
|
||||
}
|
|
@ -1,32 +1,32 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.ActivityTypes;
|
||||
import com.microsoft.bot.schema.models.ChannelAccount;
|
||||
import com.microsoft.bot.schema.models.ConversationAccount;
|
||||
|
||||
public class TestMessage {
|
||||
public static ActivityImpl Message() {
|
||||
return TestMessage.Message("1234");
|
||||
}
|
||||
|
||||
public static ActivityImpl Message(String id) {
|
||||
ActivityImpl a = new ActivityImpl()
|
||||
.withType(ActivityTypes.MESSAGE)
|
||||
.withId(id)
|
||||
.withText("test")
|
||||
.withFrom(new ChannelAccount()
|
||||
.withId("user")
|
||||
.withName("User Name"))
|
||||
.withRecipient(new ChannelAccount()
|
||||
.withId("bot")
|
||||
.withName("Bot Name"))
|
||||
.withConversation(new ConversationAccount()
|
||||
.withId("convo")
|
||||
.withName("Convo Name"))
|
||||
.withChannelId("UnitTest")
|
||||
.withServiceUrl("https://example.org");
|
||||
return a;
|
||||
}
|
||||
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.ActivityTypes;
|
||||
import com.microsoft.bot.schema.models.ChannelAccount;
|
||||
import com.microsoft.bot.schema.models.ConversationAccount;
|
||||
|
||||
public class TestMessage {
|
||||
public static ActivityImpl Message() {
|
||||
return TestMessage.Message("1234");
|
||||
}
|
||||
|
||||
public static ActivityImpl Message(String id) {
|
||||
ActivityImpl a = new ActivityImpl()
|
||||
.withType(ActivityTypes.MESSAGE)
|
||||
.withId(id)
|
||||
.withText("test")
|
||||
.withFrom(new ChannelAccount()
|
||||
.withId("user")
|
||||
.withName("User Name"))
|
||||
.withRecipient(new ChannelAccount()
|
||||
.withId("bot")
|
||||
.withName("Bot Name"))
|
||||
.withConversation(new ConversationAccount()
|
||||
.withId("convo")
|
||||
.withName("Convo Name"))
|
||||
.withChannelId("UnitTest")
|
||||
.withServiceUrl("https://example.org");
|
||||
return a;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
public class TestPocoState
|
||||
{
|
||||
private String value;
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
|
||||
public class TestPocoState
|
||||
{
|
||||
private String value;
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +1,28 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.StoreItem;
|
||||
|
||||
public class TestState implements StoreItem {
|
||||
private String etag;
|
||||
|
||||
@Override
|
||||
public String geteTag() {
|
||||
return this.etag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seteTag(String etag) {
|
||||
this.etag = etag;
|
||||
}
|
||||
|
||||
private String value;
|
||||
|
||||
public String value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void withValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.builder.StoreItem;
|
||||
|
||||
public class TestState implements StoreItem {
|
||||
private String etag;
|
||||
|
||||
@Override
|
||||
public String geteTag() {
|
||||
return this.etag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seteTag(String etag) {
|
||||
this.etag = etag;
|
||||
}
|
||||
|
||||
private String value;
|
||||
|
||||
public String value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void withValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,267 +1,267 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule;
|
||||
import com.microsoft.bot.builder.adapters.TestAdapter;
|
||||
import com.microsoft.bot.builder.adapters.TestFlow;
|
||||
import com.microsoft.bot.builder.dialogs.Dialog;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
public class TranscriptMiddlewareTest {
|
||||
|
||||
@Test
|
||||
public final void Transcript_SimpleReceive() throws Exception {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
|
||||
|
||||
new TestFlow(adapter, (ctxt) ->
|
||||
{
|
||||
|
||||
TurnContextImpl context = (TurnContextImpl) ctxt;
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
ActivityImpl typingActivity = new ActivityImpl()
|
||||
.withType(ActivityTypes.TYPING)
|
||||
.withRelatesTo(context.getActivity().relatesTo());
|
||||
try {
|
||||
ResourceResponse response = context.SendActivity(typingActivity);
|
||||
System.out.printf("Here's the response:");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
context.SendActivity("echo:" + context.getActivity().text());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}).Send("foo")
|
||||
.AssertReply((activity) -> {
|
||||
Assert.assertEquals(activity.type(), ActivityTypes.TYPING);
|
||||
return null;
|
||||
}).StartTest();
|
||||
//.AssertReply("echo:foo").StartTest();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void Transcript_MiddlewareTest() throws Exception {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TranscriptLoggerMiddleware logger = new TranscriptLoggerMiddleware(transcriptStore);
|
||||
TestAdapter adapter = new TestAdapter();
|
||||
ActivityImpl activity = ActivityImpl.CreateMessageActivity()
|
||||
.withFrom(new ChannelAccount().withName("MyAccount").withId("acctid").withRole(RoleTypes.USER));
|
||||
TurnContextImpl context = new TurnContextImpl(adapter, activity);
|
||||
NextDelegate nd = new NextDelegate() {
|
||||
@Override
|
||||
public void next() throws Exception {
|
||||
System.out.printf("Delegate called!");
|
||||
System.out.flush();
|
||||
return ;
|
||||
}
|
||||
};
|
||||
ActivityImpl typingActivity = new ActivityImpl()
|
||||
.withType(ActivityTypes.TYPING)
|
||||
.withRelatesTo(context.getActivity().relatesTo());
|
||||
try {
|
||||
context.SendActivity(typingActivity);
|
||||
System.out.printf("HI");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
|
||||
//logger.OnTurn(context, nd).get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void Transcript_LogActivities() throws ExecutionException, InterruptedException {
|
||||
Logger logger = LogManager.getLogger(Dialog.class);
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
|
||||
|
||||
String result = new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
//TurnContextImpl context = (TurnContextImpl) ctxt;
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
ActivityImpl typingActivity = new ActivityImpl()
|
||||
.withType(ActivityTypes.TYPING)
|
||||
.withRelatesTo(context.getActivity().relatesTo());
|
||||
try {
|
||||
context.SendActivity((Activity)typingActivity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
context.SendActivity("echo:" + context.getActivity().text());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
}).Send("foo")
|
||||
.AssertReply((activity) -> {
|
||||
Assert.assertEquals(activity.type(), ActivityTypes.TYPING);
|
||||
return null;
|
||||
})
|
||||
.AssertReply("echo:foo")
|
||||
.Send("bar")
|
||||
.AssertReply((activity) -> {
|
||||
Assert.assertEquals(activity.type(), ActivityTypes.TYPING);
|
||||
return null;
|
||||
})
|
||||
.AssertReply("echo:bar")
|
||||
.StartTest();
|
||||
|
||||
|
||||
PagedResult pagedResult = transcriptStore.GetTranscriptActivitiesAsync("test", conversationId[0]).join();
|
||||
Assert.assertEquals(6, pagedResult.getItems().length);
|
||||
Assert.assertEquals( "foo", ((Activity)pagedResult.getItems()[0]).text());
|
||||
Assert.assertNotEquals(((Activity)pagedResult.getItems()[1]), null);
|
||||
Assert.assertEquals("echo:foo", ((Activity) pagedResult.getItems()[2]).text());
|
||||
Assert.assertEquals("bar", ((Activity)pagedResult.getItems()[3]).text());
|
||||
|
||||
Assert.assertTrue(pagedResult.getItems()[4] != null);
|
||||
Assert.assertEquals("echo:bar", ((Activity)pagedResult.getItems()[5]).text());
|
||||
for (Object activity : pagedResult.getItems())
|
||||
{
|
||||
Assert.assertFalse(StringUtils.isBlank(((Activity) activity).id()));
|
||||
Assert.assertTrue(((Activity)activity).timestamp().isAfter(Long.MIN_VALUE));
|
||||
}
|
||||
System.out.printf("Complete");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Transcript_LogUpdateActivities() throws InterruptedException, ExecutionException {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
final Activity[] activityToUpdate = {null};
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.registerModule(new JodaModule());
|
||||
new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
if (context.getActivity().text().equals("update")) {
|
||||
activityToUpdate[0].withText("new response");
|
||||
try {
|
||||
context.UpdateActivity(activityToUpdate[0]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
ActivityImpl activity = ((ActivityImpl) context.getActivity()).CreateReply("response");
|
||||
ResourceResponse response = null;
|
||||
try {
|
||||
response = context.SendActivity(activity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
activity.withId(response.id());
|
||||
|
||||
// clone the activity, so we can use it to do an update
|
||||
activityToUpdate[0] = ActivityImpl.CloneActity(activity);
|
||||
//JsonConvert.<Activity>DeserializeObject(JsonConvert.SerializeObject(activity));
|
||||
}
|
||||
}).Send("foo")
|
||||
.Send("update")
|
||||
.AssertReply("new response")
|
||||
.StartTest();
|
||||
Thread.sleep(500);
|
||||
PagedResult pagedResult = transcriptStore.GetTranscriptActivitiesAsync("test", conversationId[0]).join();
|
||||
Assert.assertEquals(4, pagedResult.getItems().length);
|
||||
Assert.assertEquals("foo", ((Activity)pagedResult.getItems()[0]).text());
|
||||
Assert.assertEquals( "response", ((Activity)pagedResult.getItems()[1]).text());
|
||||
// TODO: Fix the following 3 asserts so they work correctly. They succeed in the travis builds and fail in the
|
||||
// BotBuilder-Java 4.0 master build.
|
||||
//Assert.assertEquals( "new response", ((Activity)pagedResult.getItems()[2]).text());
|
||||
//Assert.assertEquals("update", ((Activity)pagedResult.getItems()[3]).text());
|
||||
//Assert.assertEquals( ((Activity)pagedResult.getItems()[1]).id(), ((Activity) pagedResult.getItems()[2]).id());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void Transcript_LogDeleteActivities() throws InterruptedException, ExecutionException {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
final String[] activityId = {null};
|
||||
new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
if (context.getActivity().text().equals("deleteIt")) {
|
||||
try {
|
||||
context.DeleteActivity(activityId[0]).join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
} else {
|
||||
ActivityImpl activity = ((ActivityImpl) context.getActivity()).CreateReply("response");
|
||||
ResourceResponse response = null;
|
||||
try {
|
||||
response = context.SendActivity(activity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
activityId[0] = response.id();
|
||||
}
|
||||
|
||||
|
||||
}).Send("foo")
|
||||
.AssertReply("response")
|
||||
.Send("deleteIt")
|
||||
.StartTest();
|
||||
Thread.sleep(1500);
|
||||
PagedResult pagedResult = transcriptStore.GetTranscriptActivitiesAsync("test", conversationId[0]).join();
|
||||
for (Object act : pagedResult.getItems()) {
|
||||
System.out.printf("Here is the object: %s : Type: %s\n", act.getClass().getTypeName(), ((Activity)act).type());
|
||||
}
|
||||
|
||||
for (Object activity : pagedResult.getItems() ) {
|
||||
System.out.printf("Recipient: %s\nText: %s\n", ((Activity) activity).recipient().name(), ((Activity)activity).text());
|
||||
}
|
||||
Assert.assertEquals(4, pagedResult.getItems().length);
|
||||
Assert.assertEquals("foo", ((Activity)pagedResult.getItems()[0]).text());
|
||||
Assert.assertEquals("response", ((Activity)pagedResult.getItems()[1]).text());
|
||||
Assert.assertEquals("deleteIt", ((Activity)pagedResult.getItems()[2]).text());
|
||||
Assert.assertEquals(ActivityTypes.MESSAGE_DELETE, ((Activity)pagedResult.getItems()[3]).type());
|
||||
Assert.assertEquals(((Activity)pagedResult.getItems()[1]).id(), ((Activity) pagedResult.getItems()[3]).id());
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule;
|
||||
import com.microsoft.bot.builder.adapters.TestAdapter;
|
||||
import com.microsoft.bot.builder.adapters.TestFlow;
|
||||
import com.microsoft.bot.builder.dialogs.Dialog;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
public class TranscriptMiddlewareTest {
|
||||
|
||||
@Test
|
||||
public final void Transcript_SimpleReceive() throws Exception {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
|
||||
|
||||
new TestFlow(adapter, (ctxt) ->
|
||||
{
|
||||
|
||||
TurnContextImpl context = (TurnContextImpl) ctxt;
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
ActivityImpl typingActivity = new ActivityImpl()
|
||||
.withType(ActivityTypes.TYPING)
|
||||
.withRelatesTo(context.getActivity().relatesTo());
|
||||
try {
|
||||
ResourceResponse response = context.SendActivity(typingActivity);
|
||||
System.out.printf("Here's the response:");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
context.SendActivity("echo:" + context.getActivity().text());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}).Send("foo")
|
||||
.AssertReply((activity) -> {
|
||||
Assert.assertEquals(activity.type(), ActivityTypes.TYPING);
|
||||
return null;
|
||||
}).StartTest();
|
||||
//.AssertReply("echo:foo").StartTest();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void Transcript_MiddlewareTest() throws Exception {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TranscriptLoggerMiddleware logger = new TranscriptLoggerMiddleware(transcriptStore);
|
||||
TestAdapter adapter = new TestAdapter();
|
||||
ActivityImpl activity = ActivityImpl.CreateMessageActivity()
|
||||
.withFrom(new ChannelAccount().withName("MyAccount").withId("acctid").withRole(RoleTypes.USER));
|
||||
TurnContextImpl context = new TurnContextImpl(adapter, activity);
|
||||
NextDelegate nd = new NextDelegate() {
|
||||
@Override
|
||||
public void next() throws Exception {
|
||||
System.out.printf("Delegate called!");
|
||||
System.out.flush();
|
||||
return ;
|
||||
}
|
||||
};
|
||||
ActivityImpl typingActivity = new ActivityImpl()
|
||||
.withType(ActivityTypes.TYPING)
|
||||
.withRelatesTo(context.getActivity().relatesTo());
|
||||
try {
|
||||
context.SendActivity(typingActivity);
|
||||
System.out.printf("HI");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
|
||||
//logger.OnTurn(context, nd).get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void Transcript_LogActivities() throws ExecutionException, InterruptedException {
|
||||
Logger logger = LogManager.getLogger(Dialog.class);
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
|
||||
|
||||
String result = new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
//TurnContextImpl context = (TurnContextImpl) ctxt;
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
ActivityImpl typingActivity = new ActivityImpl()
|
||||
.withType(ActivityTypes.TYPING)
|
||||
.withRelatesTo(context.getActivity().relatesTo());
|
||||
try {
|
||||
context.SendActivity((Activity)typingActivity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
try {
|
||||
context.SendActivity("echo:" + context.getActivity().text());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
}).Send("foo")
|
||||
.AssertReply((activity) -> {
|
||||
Assert.assertEquals(activity.type(), ActivityTypes.TYPING);
|
||||
return null;
|
||||
})
|
||||
.AssertReply("echo:foo")
|
||||
.Send("bar")
|
||||
.AssertReply((activity) -> {
|
||||
Assert.assertEquals(activity.type(), ActivityTypes.TYPING);
|
||||
return null;
|
||||
})
|
||||
.AssertReply("echo:bar")
|
||||
.StartTest();
|
||||
|
||||
|
||||
PagedResult pagedResult = transcriptStore.GetTranscriptActivitiesAsync("test", conversationId[0]).join();
|
||||
Assert.assertEquals(6, pagedResult.getItems().length);
|
||||
Assert.assertEquals( "foo", ((Activity)pagedResult.getItems()[0]).text());
|
||||
Assert.assertNotEquals(((Activity)pagedResult.getItems()[1]), null);
|
||||
Assert.assertEquals("echo:foo", ((Activity) pagedResult.getItems()[2]).text());
|
||||
Assert.assertEquals("bar", ((Activity)pagedResult.getItems()[3]).text());
|
||||
|
||||
Assert.assertTrue(pagedResult.getItems()[4] != null);
|
||||
Assert.assertEquals("echo:bar", ((Activity)pagedResult.getItems()[5]).text());
|
||||
for (Object activity : pagedResult.getItems())
|
||||
{
|
||||
Assert.assertFalse(StringUtils.isBlank(((Activity) activity).id()));
|
||||
Assert.assertTrue(((Activity)activity).timestamp().isAfter(Long.MIN_VALUE));
|
||||
}
|
||||
System.out.printf("Complete");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Transcript_LogUpdateActivities() throws InterruptedException, ExecutionException {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
final Activity[] activityToUpdate = {null};
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.registerModule(new JodaModule());
|
||||
new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
if (context.getActivity().text().equals("update")) {
|
||||
activityToUpdate[0].withText("new response");
|
||||
try {
|
||||
context.UpdateActivity(activityToUpdate[0]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
ActivityImpl activity = ((ActivityImpl) context.getActivity()).CreateReply("response");
|
||||
ResourceResponse response = null;
|
||||
try {
|
||||
response = context.SendActivity(activity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
activity.withId(response.id());
|
||||
|
||||
// clone the activity, so we can use it to do an update
|
||||
activityToUpdate[0] = ActivityImpl.CloneActity(activity);
|
||||
//JsonConvert.<Activity>DeserializeObject(JsonConvert.SerializeObject(activity));
|
||||
}
|
||||
}).Send("foo")
|
||||
.Send("update")
|
||||
.AssertReply("new response")
|
||||
.StartTest();
|
||||
Thread.sleep(500);
|
||||
PagedResult pagedResult = transcriptStore.GetTranscriptActivitiesAsync("test", conversationId[0]).join();
|
||||
Assert.assertEquals(4, pagedResult.getItems().length);
|
||||
Assert.assertEquals("foo", ((Activity)pagedResult.getItems()[0]).text());
|
||||
Assert.assertEquals( "response", ((Activity)pagedResult.getItems()[1]).text());
|
||||
// TODO: Fix the following 3 asserts so they work correctly. They succeed in the travis builds and fail in the
|
||||
// BotBuilder-Java 4.0 master build.
|
||||
//Assert.assertEquals( "new response", ((Activity)pagedResult.getItems()[2]).text());
|
||||
//Assert.assertEquals("update", ((Activity)pagedResult.getItems()[3]).text());
|
||||
//Assert.assertEquals( ((Activity)pagedResult.getItems()[1]).id(), ((Activity) pagedResult.getItems()[2]).id());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void Transcript_LogDeleteActivities() throws InterruptedException, ExecutionException {
|
||||
MemoryTranscriptStore transcriptStore = new MemoryTranscriptStore();
|
||||
TestAdapter adapter = (new TestAdapter()).Use(new TranscriptLoggerMiddleware(transcriptStore));
|
||||
final String[] conversationId = {null};
|
||||
final String[] activityId = {null};
|
||||
new TestFlow(adapter, (context) ->
|
||||
{
|
||||
|
||||
conversationId[0] = context.getActivity().conversation().id();
|
||||
if (context.getActivity().text().equals("deleteIt")) {
|
||||
try {
|
||||
context.DeleteActivity(activityId[0]).join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
} else {
|
||||
ActivityImpl activity = ((ActivityImpl) context.getActivity()).CreateReply("response");
|
||||
ResourceResponse response = null;
|
||||
try {
|
||||
response = context.SendActivity(activity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
activityId[0] = response.id();
|
||||
}
|
||||
|
||||
|
||||
}).Send("foo")
|
||||
.AssertReply("response")
|
||||
.Send("deleteIt")
|
||||
.StartTest();
|
||||
Thread.sleep(1500);
|
||||
PagedResult pagedResult = transcriptStore.GetTranscriptActivitiesAsync("test", conversationId[0]).join();
|
||||
for (Object act : pagedResult.getItems()) {
|
||||
System.out.printf("Here is the object: %s : Type: %s\n", act.getClass().getTypeName(), ((Activity)act).type());
|
||||
}
|
||||
|
||||
for (Object activity : pagedResult.getItems() ) {
|
||||
System.out.printf("Recipient: %s\nText: %s\n", ((Activity) activity).recipient().name(), ((Activity)activity).text());
|
||||
}
|
||||
Assert.assertEquals(4, pagedResult.getItems().length);
|
||||
Assert.assertEquals("foo", ((Activity)pagedResult.getItems()[0]).text());
|
||||
Assert.assertEquals("response", ((Activity)pagedResult.getItems()[1]).text());
|
||||
Assert.assertEquals("deleteIt", ((Activity)pagedResult.getItems()[2]).text());
|
||||
Assert.assertEquals(ActivityTypes.MESSAGE_DELETE, ((Activity)pagedResult.getItems()[3]).type());
|
||||
Assert.assertEquals(((Activity)pagedResult.getItems()[1]).id(), ((Activity) pagedResult.getItems()[3]).id());
|
||||
}
|
||||
}
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,17 +1,17 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class TypedObject {
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public TypedObject withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class TypedObject {
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public TypedObject withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
public class WasCalledMiddlware implements Middleware {
|
||||
boolean called = false;
|
||||
public boolean getCalled() {
|
||||
return this.called;
|
||||
}
|
||||
public void setCalled(boolean called) {
|
||||
this.called = called;
|
||||
}
|
||||
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
setCalled(true);
|
||||
next.next();
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public class WasCalledMiddlware implements Middleware {
|
||||
boolean called = false;
|
||||
public boolean getCalled() {
|
||||
return this.called;
|
||||
}
|
||||
public void setCalled(boolean called) {
|
||||
this.called = called;
|
||||
}
|
||||
|
||||
public void OnTurn(TurnContext context, NextDelegate next) throws Exception {
|
||||
setCalled(true);
|
||||
next.next();
|
||||
}
|
||||
}
|
|
@ -1,468 +1,468 @@
|
|||
package com.microsoft.bot.builder.adapters;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
|
||||
public class TestFlow {
|
||||
final TestAdapter adapter;
|
||||
CompletableFuture<String> testTask;
|
||||
Consumer<TurnContext> callback;
|
||||
|
||||
ArrayList<Supplier<String>> tasks = new ArrayList<Supplier<String>>();
|
||||
ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory()
|
||||
{
|
||||
@Override
|
||||
public ForkJoinWorkerThread newThread(ForkJoinPool pool)
|
||||
{
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName("TestFlow-" + worker.getPoolIndex());
|
||||
return worker;
|
||||
}
|
||||
};
|
||||
|
||||
ExecutorService executor = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, true);
|
||||
|
||||
|
||||
public TestFlow(TestAdapter adapter) {
|
||||
this(adapter, null);
|
||||
}
|
||||
|
||||
public TestFlow(TestAdapter adapter, Consumer<TurnContext> callback) {
|
||||
this.adapter = adapter;
|
||||
this.callback = callback;
|
||||
this.testTask = completedFuture(null);
|
||||
}
|
||||
|
||||
|
||||
public TestFlow(Supplier<String> testTask, TestFlow flow) {
|
||||
this.tasks = flow.tasks;
|
||||
if (testTask != null)
|
||||
this.tasks.add(testTask);
|
||||
this.callback = flow.callback;
|
||||
this.adapter = flow.adapter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start the execution of the test flow
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String StartTest() throws ExecutionException, InterruptedException {
|
||||
|
||||
System.out.printf("+------------------------------------------+\n");
|
||||
int count = 0;
|
||||
for (Supplier<String> task : this.tasks) {
|
||||
System.out.printf("| Running task %s of %s\n", count++, this.tasks.size());
|
||||
String result = null;
|
||||
result = task.get();
|
||||
System.out.printf("| --> Result: %s", result);
|
||||
System.out.flush();
|
||||
}
|
||||
System.out.printf("+------------------------------------------+\n");
|
||||
return "Completed";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message from the user to the bot
|
||||
*
|
||||
* @param userSays
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Send(String userSays) throws IllegalArgumentException {
|
||||
if (userSays == null)
|
||||
throw new IllegalArgumentException("You have to pass a userSays parameter");
|
||||
|
||||
// Function<TurnContextImpl, CompletableFuture>
|
||||
return new TestFlow((() -> {
|
||||
System.out.print(String.format("USER SAYS: %s (Thread Id: %s)\n", userSays, Thread.currentThread().getId()));
|
||||
System.out.flush();
|
||||
try {
|
||||
this.adapter.SendTextToBot(userSays, this.callback);
|
||||
return "Successfully sent " + userSays;
|
||||
} catch (Exception e) {
|
||||
Assert.fail(e.getMessage());
|
||||
return e.getMessage();
|
||||
}
|
||||
}), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an activity from the user to the bot
|
||||
*
|
||||
* @param userActivity
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Send(Activity userActivity) {
|
||||
if (userActivity == null)
|
||||
throw new IllegalArgumentException("You have to pass an Activity");
|
||||
|
||||
return new TestFlow((() -> {
|
||||
System.out.printf("TestFlow(%s): Send with User Activity! %s", Thread.currentThread().getId(), userActivity.text());
|
||||
System.out.flush();
|
||||
|
||||
|
||||
try {
|
||||
this.adapter.ProcessActivity((ActivityImpl) userActivity, this.callback);
|
||||
return "TestFlow: Send() -> ProcessActivity: " + userActivity.text();
|
||||
} catch (Exception e) {
|
||||
return e.getMessage();
|
||||
|
||||
}
|
||||
|
||||
}), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay for time period
|
||||
*
|
||||
* @param ms
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Delay(int ms) {
|
||||
return new TestFlow(() ->
|
||||
{
|
||||
System.out.printf("TestFlow(%s): Delay(%s ms) called. ", Thread.currentThread().getId(), ms);
|
||||
System.out.flush();
|
||||
try {
|
||||
Thread.sleep((int) ms);
|
||||
} catch (InterruptedException e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
return null;
|
||||
}, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that reply is expected text
|
||||
*
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReply(String expected) {
|
||||
return this.AssertReply(expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(String expected, String description) {
|
||||
return this.AssertReply(expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(String expected, String description, int timeout) {
|
||||
return this.AssertReply(this.adapter.MakeActivity(expected), description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the reply is expected activity
|
||||
*
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReply(Activity expected) {
|
||||
String description = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||
return AssertReply(expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(Activity expected, String description, int timeout) {
|
||||
if (description == null)
|
||||
description = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||
String finalDescription = description;
|
||||
return this.AssertReply((reply) -> {
|
||||
if (expected.type() != reply.type())
|
||||
return String.format("%s: Type should match", finalDescription);
|
||||
if (expected.text().equals(reply.text())) {
|
||||
if (finalDescription == null)
|
||||
return String.format("Expected:%s\nReceived:{reply.AsMessageActivity().Text}", expected.text());
|
||||
else
|
||||
return String.format("%s: Text should match", finalDescription);
|
||||
}
|
||||
// TODO, expand this to do all properties set on expected
|
||||
return null;
|
||||
}, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the reply matches a custom validation routine
|
||||
*
|
||||
* @param validateActivity
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReply(Function<Activity, String> validateActivity) {
|
||||
String description = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||
return AssertReply(validateActivity, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(Function<Activity, String> validateActivity, String description) {
|
||||
return AssertReply(validateActivity, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(Function<Activity, String> validateActivity, String description, int timeout) {
|
||||
return new TestFlow(() -> {
|
||||
System.out.println(String.format("AssertReply: Starting loop : %s (Thread:%s)", description, Thread.currentThread().getId()));
|
||||
System.out.flush();
|
||||
|
||||
int finalTimeout = Integer.MAX_VALUE;
|
||||
if (isDebug())
|
||||
finalTimeout = Integer.MAX_VALUE;
|
||||
|
||||
DateTime start = DateTime.now();
|
||||
while (true) {
|
||||
DateTime current = DateTime.now();
|
||||
|
||||
if ((current.getMillis() - start.getMillis()) > (long) finalTimeout) {
|
||||
System.out.println("AssertReply: Timeout!\n");
|
||||
System.out.flush();
|
||||
return String.format("%d ms Timed out waiting for:'%s'", finalTimeout, description);
|
||||
}
|
||||
|
||||
// System.out.println("Before GetNextReply\n");
|
||||
// System.out.flush();
|
||||
|
||||
Activity replyActivity = this.adapter.GetNextReply();
|
||||
// System.out.println("After GetNextReply\n");
|
||||
// System.out.flush();
|
||||
|
||||
if (replyActivity != null) {
|
||||
System.out.printf("AssertReply(tid:%s): Received Reply: %s ", Thread.currentThread().getId(), (replyActivity.text() == null) ? "No Text set" : replyActivity.text());
|
||||
System.out.flush();
|
||||
System.out.printf("=============\n From: %s\n To:%s\n ==========\n", (replyActivity.from() == null) ? "No from set" : replyActivity.from().name(),
|
||||
(replyActivity.recipient() == null) ? "No recipient set" : replyActivity.recipient().name());
|
||||
System.out.flush();
|
||||
|
||||
// if we have a reply
|
||||
return validateActivity.apply(replyActivity);
|
||||
} else {
|
||||
System.out.printf("AssertReply(tid:%s): Waiting..\n", Thread.currentThread().getId());
|
||||
System.out.flush();
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
// Hack to determine if debugger attached..
|
||||
public boolean isDebug() {
|
||||
for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
|
||||
if (arg.contains("jdwp=")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Turn(String userSays, String expected, String description, int timeout) {
|
||||
String result = null;
|
||||
try {
|
||||
|
||||
result = CompletableFuture.supplyAsync(() -> { // Send the message
|
||||
|
||||
if (userSays == null)
|
||||
throw new IllegalArgumentException("You have to pass a userSays parameter");
|
||||
|
||||
System.out.print(String.format("TestTurn(%s): USER SAYS: %s \n", Thread.currentThread().getId(), userSays));
|
||||
System.out.flush();
|
||||
|
||||
try {
|
||||
this.adapter.SendTextToBot(userSays, this.callback);
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
|
||||
})
|
||||
.thenApply(arg -> { // Assert Reply
|
||||
int finalTimeout = Integer.MAX_VALUE;
|
||||
if (isDebug())
|
||||
finalTimeout = Integer.MAX_VALUE;
|
||||
Function<Activity, String> validateActivity = activity -> {
|
||||
if (activity.text().equals(expected)) {
|
||||
System.out.println(String.format("TestTurn(tid:%s): Validated text is: %s", Thread.currentThread().getId(), expected));
|
||||
System.out.flush();
|
||||
|
||||
return "SUCCESS";
|
||||
}
|
||||
System.out.println(String.format("TestTurn(tid:%s): Failed validate text is: %s", Thread.currentThread().getId(), expected));
|
||||
System.out.flush();
|
||||
|
||||
return String.format("FAIL: %s received in Activity.text (%s expected)", activity.text(), expected);
|
||||
};
|
||||
|
||||
|
||||
System.out.println(String.format("TestTurn(tid:%s): Started receive loop: %s", Thread.currentThread().getId(), description));
|
||||
System.out.flush();
|
||||
DateTime start = DateTime.now();
|
||||
while (true) {
|
||||
DateTime current = DateTime.now();
|
||||
|
||||
if ((current.getMillis() - start.getMillis()) > (long) finalTimeout)
|
||||
return String.format("TestTurn: %d ms Timed out waiting for:'%s'", finalTimeout, description);
|
||||
|
||||
|
||||
Activity replyActivity = this.adapter.GetNextReply();
|
||||
|
||||
|
||||
if (replyActivity != null) {
|
||||
// if we have a reply
|
||||
System.out.println(String.format("TestTurn(tid:%s): Received Reply: %s",
|
||||
Thread.currentThread().getId(),
|
||||
String.format("\n========\n To:%s\n From:%s\n Msg:%s\n=======", replyActivity.recipient().name(), replyActivity.from().name(), replyActivity.text())
|
||||
));
|
||||
System.out.flush();
|
||||
return validateActivity.apply(replyActivity);
|
||||
} else {
|
||||
System.out.println(String.format("TestTurn(tid:%s): No reply..", Thread.currentThread().getId()));
|
||||
System.out.flush();
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.get(timeout, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
} catch (TimeoutException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Say() -> shortcut for .Send(user).AssertReply(Expected)
|
||||
*
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Test(String userSays, String expected) {
|
||||
return Test(userSays, expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, String expected, String description) {
|
||||
return Test(userSays, expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, String expected, String description, int timeout) {
|
||||
if (expected == null)
|
||||
throw new IllegalArgumentException("expected");
|
||||
|
||||
return this.Send(userSays)
|
||||
.AssertReply(expected, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test() -> shortcut for .Send(user).AssertReply(Expected)
|
||||
*
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Test(String userSays, Activity expected) {
|
||||
return Test(userSays, expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Activity expected, String description) {
|
||||
return Test(userSays, expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Activity expected, String description, int timeout) {
|
||||
if (expected == null)
|
||||
throw new IllegalArgumentException("expected");
|
||||
|
||||
return this.Send(userSays)
|
||||
.AssertReply(expected, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Say() -> shortcut for .Send(user).AssertReply(Expected)
|
||||
*
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Test(String userSays, Function<Activity, String> expected) {
|
||||
return Test(userSays, expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Function<Activity, String> expected, String description) {
|
||||
return Test(userSays, expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Function<Activity, String> expected, String description, int timeout) {
|
||||
if (expected == null)
|
||||
throw new IllegalArgumentException("expected");
|
||||
|
||||
return this.Send(userSays)
|
||||
.AssertReply(expected, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that reply is one of the candidate responses
|
||||
*
|
||||
* @param candidates
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReplyOneOf(String[] candidates) {
|
||||
return AssertReplyOneOf(candidates, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReplyOneOf(String[] candidates, String description) {
|
||||
return AssertReplyOneOf(candidates, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReplyOneOf(String[] candidates, String description, int timeout) {
|
||||
if (candidates == null)
|
||||
throw new IllegalArgumentException("candidates");
|
||||
|
||||
return this.AssertReply((reply) -> {
|
||||
for (String candidate : candidates) {
|
||||
if (reply.text() == candidate)
|
||||
return null;
|
||||
}
|
||||
return String.format("%s: Not one of candidates: %s", description, String.join("\n ", candidates));
|
||||
}, description, timeout);
|
||||
}
|
||||
|
||||
}
|
||||
package com.microsoft.bot.builder.adapters;
|
||||
|
||||
import com.microsoft.bot.builder.TurnContext;
|
||||
import com.microsoft.bot.schema.ActivityImpl;
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
|
||||
public class TestFlow {
|
||||
final TestAdapter adapter;
|
||||
CompletableFuture<String> testTask;
|
||||
Consumer<TurnContext> callback;
|
||||
|
||||
ArrayList<Supplier<String>> tasks = new ArrayList<Supplier<String>>();
|
||||
ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory()
|
||||
{
|
||||
@Override
|
||||
public ForkJoinWorkerThread newThread(ForkJoinPool pool)
|
||||
{
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName("TestFlow-" + worker.getPoolIndex());
|
||||
return worker;
|
||||
}
|
||||
};
|
||||
|
||||
ExecutorService executor = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, true);
|
||||
|
||||
|
||||
public TestFlow(TestAdapter adapter) {
|
||||
this(adapter, null);
|
||||
}
|
||||
|
||||
public TestFlow(TestAdapter adapter, Consumer<TurnContext> callback) {
|
||||
this.adapter = adapter;
|
||||
this.callback = callback;
|
||||
this.testTask = completedFuture(null);
|
||||
}
|
||||
|
||||
|
||||
public TestFlow(Supplier<String> testTask, TestFlow flow) {
|
||||
this.tasks = flow.tasks;
|
||||
if (testTask != null)
|
||||
this.tasks.add(testTask);
|
||||
this.callback = flow.callback;
|
||||
this.adapter = flow.adapter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start the execution of the test flow
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String StartTest() throws ExecutionException, InterruptedException {
|
||||
|
||||
System.out.printf("+------------------------------------------+\n");
|
||||
int count = 0;
|
||||
for (Supplier<String> task : this.tasks) {
|
||||
System.out.printf("| Running task %s of %s\n", count++, this.tasks.size());
|
||||
String result = null;
|
||||
result = task.get();
|
||||
System.out.printf("| --> Result: %s", result);
|
||||
System.out.flush();
|
||||
}
|
||||
System.out.printf("+------------------------------------------+\n");
|
||||
return "Completed";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message from the user to the bot
|
||||
*
|
||||
* @param userSays
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Send(String userSays) throws IllegalArgumentException {
|
||||
if (userSays == null)
|
||||
throw new IllegalArgumentException("You have to pass a userSays parameter");
|
||||
|
||||
// Function<TurnContextImpl, CompletableFuture>
|
||||
return new TestFlow((() -> {
|
||||
System.out.print(String.format("USER SAYS: %s (Thread Id: %s)\n", userSays, Thread.currentThread().getId()));
|
||||
System.out.flush();
|
||||
try {
|
||||
this.adapter.SendTextToBot(userSays, this.callback);
|
||||
return "Successfully sent " + userSays;
|
||||
} catch (Exception e) {
|
||||
Assert.fail(e.getMessage());
|
||||
return e.getMessage();
|
||||
}
|
||||
}), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an activity from the user to the bot
|
||||
*
|
||||
* @param userActivity
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Send(Activity userActivity) {
|
||||
if (userActivity == null)
|
||||
throw new IllegalArgumentException("You have to pass an Activity");
|
||||
|
||||
return new TestFlow((() -> {
|
||||
System.out.printf("TestFlow(%s): Send with User Activity! %s", Thread.currentThread().getId(), userActivity.text());
|
||||
System.out.flush();
|
||||
|
||||
|
||||
try {
|
||||
this.adapter.ProcessActivity((ActivityImpl) userActivity, this.callback);
|
||||
return "TestFlow: Send() -> ProcessActivity: " + userActivity.text();
|
||||
} catch (Exception e) {
|
||||
return e.getMessage();
|
||||
|
||||
}
|
||||
|
||||
}), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay for time period
|
||||
*
|
||||
* @param ms
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Delay(int ms) {
|
||||
return new TestFlow(() ->
|
||||
{
|
||||
System.out.printf("TestFlow(%s): Delay(%s ms) called. ", Thread.currentThread().getId(), ms);
|
||||
System.out.flush();
|
||||
try {
|
||||
Thread.sleep((int) ms);
|
||||
} catch (InterruptedException e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
return null;
|
||||
}, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that reply is expected text
|
||||
*
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReply(String expected) {
|
||||
return this.AssertReply(expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(String expected, String description) {
|
||||
return this.AssertReply(expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(String expected, String description, int timeout) {
|
||||
return this.AssertReply(this.adapter.MakeActivity(expected), description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the reply is expected activity
|
||||
*
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReply(Activity expected) {
|
||||
String description = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||
return AssertReply(expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(Activity expected, String description, int timeout) {
|
||||
if (description == null)
|
||||
description = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||
String finalDescription = description;
|
||||
return this.AssertReply((reply) -> {
|
||||
if (expected.type() != reply.type())
|
||||
return String.format("%s: Type should match", finalDescription);
|
||||
if (expected.text().equals(reply.text())) {
|
||||
if (finalDescription == null)
|
||||
return String.format("Expected:%s\nReceived:{reply.AsMessageActivity().Text}", expected.text());
|
||||
else
|
||||
return String.format("%s: Text should match", finalDescription);
|
||||
}
|
||||
// TODO, expand this to do all properties set on expected
|
||||
return null;
|
||||
}, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the reply matches a custom validation routine
|
||||
*
|
||||
* @param validateActivity
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReply(Function<Activity, String> validateActivity) {
|
||||
String description = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||
return AssertReply(validateActivity, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(Function<Activity, String> validateActivity, String description) {
|
||||
return AssertReply(validateActivity, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReply(Function<Activity, String> validateActivity, String description, int timeout) {
|
||||
return new TestFlow(() -> {
|
||||
System.out.println(String.format("AssertReply: Starting loop : %s (Thread:%s)", description, Thread.currentThread().getId()));
|
||||
System.out.flush();
|
||||
|
||||
int finalTimeout = Integer.MAX_VALUE;
|
||||
if (isDebug())
|
||||
finalTimeout = Integer.MAX_VALUE;
|
||||
|
||||
DateTime start = DateTime.now();
|
||||
while (true) {
|
||||
DateTime current = DateTime.now();
|
||||
|
||||
if ((current.getMillis() - start.getMillis()) > (long) finalTimeout) {
|
||||
System.out.println("AssertReply: Timeout!\n");
|
||||
System.out.flush();
|
||||
return String.format("%d ms Timed out waiting for:'%s'", finalTimeout, description);
|
||||
}
|
||||
|
||||
// System.out.println("Before GetNextReply\n");
|
||||
// System.out.flush();
|
||||
|
||||
Activity replyActivity = this.adapter.GetNextReply();
|
||||
// System.out.println("After GetNextReply\n");
|
||||
// System.out.flush();
|
||||
|
||||
if (replyActivity != null) {
|
||||
System.out.printf("AssertReply(tid:%s): Received Reply: %s ", Thread.currentThread().getId(), (replyActivity.text() == null) ? "No Text set" : replyActivity.text());
|
||||
System.out.flush();
|
||||
System.out.printf("=============\n From: %s\n To:%s\n ==========\n", (replyActivity.from() == null) ? "No from set" : replyActivity.from().name(),
|
||||
(replyActivity.recipient() == null) ? "No recipient set" : replyActivity.recipient().name());
|
||||
System.out.flush();
|
||||
|
||||
// if we have a reply
|
||||
return validateActivity.apply(replyActivity);
|
||||
} else {
|
||||
System.out.printf("AssertReply(tid:%s): Waiting..\n", Thread.currentThread().getId());
|
||||
System.out.flush();
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
// Hack to determine if debugger attached..
|
||||
public boolean isDebug() {
|
||||
for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
|
||||
if (arg.contains("jdwp=")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Turn(String userSays, String expected, String description, int timeout) {
|
||||
String result = null;
|
||||
try {
|
||||
|
||||
result = CompletableFuture.supplyAsync(() -> { // Send the message
|
||||
|
||||
if (userSays == null)
|
||||
throw new IllegalArgumentException("You have to pass a userSays parameter");
|
||||
|
||||
System.out.print(String.format("TestTurn(%s): USER SAYS: %s \n", Thread.currentThread().getId(), userSays));
|
||||
System.out.flush();
|
||||
|
||||
try {
|
||||
this.adapter.SendTextToBot(userSays, this.callback);
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
|
||||
})
|
||||
.thenApply(arg -> { // Assert Reply
|
||||
int finalTimeout = Integer.MAX_VALUE;
|
||||
if (isDebug())
|
||||
finalTimeout = Integer.MAX_VALUE;
|
||||
Function<Activity, String> validateActivity = activity -> {
|
||||
if (activity.text().equals(expected)) {
|
||||
System.out.println(String.format("TestTurn(tid:%s): Validated text is: %s", Thread.currentThread().getId(), expected));
|
||||
System.out.flush();
|
||||
|
||||
return "SUCCESS";
|
||||
}
|
||||
System.out.println(String.format("TestTurn(tid:%s): Failed validate text is: %s", Thread.currentThread().getId(), expected));
|
||||
System.out.flush();
|
||||
|
||||
return String.format("FAIL: %s received in Activity.text (%s expected)", activity.text(), expected);
|
||||
};
|
||||
|
||||
|
||||
System.out.println(String.format("TestTurn(tid:%s): Started receive loop: %s", Thread.currentThread().getId(), description));
|
||||
System.out.flush();
|
||||
DateTime start = DateTime.now();
|
||||
while (true) {
|
||||
DateTime current = DateTime.now();
|
||||
|
||||
if ((current.getMillis() - start.getMillis()) > (long) finalTimeout)
|
||||
return String.format("TestTurn: %d ms Timed out waiting for:'%s'", finalTimeout, description);
|
||||
|
||||
|
||||
Activity replyActivity = this.adapter.GetNextReply();
|
||||
|
||||
|
||||
if (replyActivity != null) {
|
||||
// if we have a reply
|
||||
System.out.println(String.format("TestTurn(tid:%s): Received Reply: %s",
|
||||
Thread.currentThread().getId(),
|
||||
String.format("\n========\n To:%s\n From:%s\n Msg:%s\n=======", replyActivity.recipient().name(), replyActivity.from().name(), replyActivity.text())
|
||||
));
|
||||
System.out.flush();
|
||||
return validateActivity.apply(replyActivity);
|
||||
} else {
|
||||
System.out.println(String.format("TestTurn(tid:%s): No reply..", Thread.currentThread().getId()));
|
||||
System.out.flush();
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.get(timeout, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
} catch (TimeoutException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Say() -> shortcut for .Send(user).AssertReply(Expected)
|
||||
*
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Test(String userSays, String expected) {
|
||||
return Test(userSays, expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, String expected, String description) {
|
||||
return Test(userSays, expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, String expected, String description, int timeout) {
|
||||
if (expected == null)
|
||||
throw new IllegalArgumentException("expected");
|
||||
|
||||
return this.Send(userSays)
|
||||
.AssertReply(expected, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test() -> shortcut for .Send(user).AssertReply(Expected)
|
||||
*
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Test(String userSays, Activity expected) {
|
||||
return Test(userSays, expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Activity expected, String description) {
|
||||
return Test(userSays, expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Activity expected, String description, int timeout) {
|
||||
if (expected == null)
|
||||
throw new IllegalArgumentException("expected");
|
||||
|
||||
return this.Send(userSays)
|
||||
.AssertReply(expected, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Say() -> shortcut for .Send(user).AssertReply(Expected)
|
||||
*
|
||||
* @param userSays
|
||||
* @param expected
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow Test(String userSays, Function<Activity, String> expected) {
|
||||
return Test(userSays, expected, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Function<Activity, String> expected, String description) {
|
||||
return Test(userSays, expected, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow Test(String userSays, Function<Activity, String> expected, String description, int timeout) {
|
||||
if (expected == null)
|
||||
throw new IllegalArgumentException("expected");
|
||||
|
||||
return this.Send(userSays)
|
||||
.AssertReply(expected, description, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that reply is one of the candidate responses
|
||||
*
|
||||
* @param candidates
|
||||
* @param description
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public TestFlow AssertReplyOneOf(String[] candidates) {
|
||||
return AssertReplyOneOf(candidates, null, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReplyOneOf(String[] candidates, String description) {
|
||||
return AssertReplyOneOf(candidates, description, 3000);
|
||||
}
|
||||
|
||||
public TestFlow AssertReplyOneOf(String[] candidates, String description, int timeout) {
|
||||
if (candidates == null)
|
||||
throw new IllegalArgumentException("candidates");
|
||||
|
||||
return this.AssertReply((reply) -> {
|
||||
for (String candidate : candidates) {
|
||||
if (reply.text() == candidate)
|
||||
return null;
|
||||
}
|
||||
return String.format("%s: Not one of candidates: %s", description, String.join("\n ", candidates));
|
||||
}, description, timeout);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,327 +1,327 @@
|
|||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import okhttp3.*;
|
||||
import okhttp3.internal.Util;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class InterceptorManager {
|
||||
|
||||
private final static String RECORD_FOLDER = "session-records/";
|
||||
|
||||
private Map<String, String> textReplacementRules = new HashMap<String, String>();
|
||||
// Stores a map of all the HTTP properties in a session
|
||||
// A state machine ensuring a test is always reset before another one is setup
|
||||
|
||||
protected RecordedData recordedData;
|
||||
|
||||
private final String testName;
|
||||
|
||||
private final TestBase.TestMode testMode;
|
||||
|
||||
private InterceptorManager(String testName, TestBase.TestMode testMode) {
|
||||
this.testName = testName;
|
||||
this.testMode = testMode;
|
||||
}
|
||||
|
||||
public void addTextReplacementRule(String regex, String replacement) {
|
||||
textReplacementRules.put(regex, replacement);
|
||||
}
|
||||
|
||||
// factory method
|
||||
public static InterceptorManager create(String testName, TestBase.TestMode testMode) throws IOException {
|
||||
InterceptorManager interceptorManager = new InterceptorManager(testName, testMode);
|
||||
|
||||
return interceptorManager;
|
||||
}
|
||||
|
||||
public boolean isRecordMode() {
|
||||
return testMode == TestBase.TestMode.RECORD;
|
||||
}
|
||||
|
||||
public boolean isPlaybackMode() {
|
||||
return testMode == TestBase.TestMode.PLAYBACK;
|
||||
}
|
||||
|
||||
public Interceptor initInterceptor() throws IOException {
|
||||
switch (testMode) {
|
||||
case RECORD:
|
||||
recordedData = new RecordedData();
|
||||
return new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return record(chain);
|
||||
}
|
||||
};
|
||||
case PLAYBACK:
|
||||
readDataFromFile();
|
||||
return new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return playback(chain);
|
||||
}
|
||||
};
|
||||
default:
|
||||
System.out.println("==> Unknown AZURE_TEST_MODE: " + testMode);
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
public void finalizeInterceptor() throws IOException {
|
||||
switch (testMode) {
|
||||
case RECORD:
|
||||
writeDataToFile();
|
||||
break;
|
||||
case PLAYBACK:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
System.out.println("==> Unknown AZURE_TEST_MODE: " + testMode);
|
||||
};
|
||||
}
|
||||
|
||||
private Response record(Interceptor.Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
NetworkCallRecord networkCallRecord = new NetworkCallRecord();
|
||||
|
||||
networkCallRecord.Headers = new HashMap<>();
|
||||
|
||||
if (request.header("Content-Type") != null) {
|
||||
networkCallRecord.Headers.put("Content-Type", request.header("Content-Type"));
|
||||
}
|
||||
if (request.header("x-ms-version") != null) {
|
||||
networkCallRecord.Headers.put("x-ms-version", request.header("x-ms-version"));
|
||||
}
|
||||
if (request.header("User-Agent") != null) {
|
||||
networkCallRecord.Headers.put("User-Agent", request.header("User-Agent"));
|
||||
}
|
||||
|
||||
networkCallRecord.Method = request.method();
|
||||
networkCallRecord.Uri = applyReplacementRule(request.url().toString().replaceAll("\\?$", ""));
|
||||
|
||||
networkCallRecord.Body = bodyToString(request);
|
||||
|
||||
Response response = chain.proceed(request);
|
||||
|
||||
networkCallRecord.Response = new HashMap<>();
|
||||
networkCallRecord.Response.put("StatusCode", Integer.toString(response.code()));
|
||||
extractResponseData(networkCallRecord.Response, response);
|
||||
|
||||
// remove pre-added header if this is a waiting or redirection
|
||||
if (networkCallRecord.Response.get("Body") != null) {
|
||||
if (networkCallRecord.Response.get("Body").contains("<Status>InProgress</Status>")
|
||||
|| Integer.parseInt(networkCallRecord.Response.get("StatusCode")) == 307) {
|
||||
// Do nothing
|
||||
} else {
|
||||
synchronized (recordedData.getNetworkCallRecords()) {
|
||||
recordedData.getNetworkCallRecords().add(networkCallRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private String bodyToString(final Request request) {
|
||||
try {
|
||||
final Buffer buffer = new Buffer();
|
||||
|
||||
request.newBuilder().build().body().writeTo(buffer);
|
||||
return buffer.readUtf8();
|
||||
} catch (final Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private Response playback(Interceptor.Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
String incomingUrl = applyReplacementRule(request.url().toString());
|
||||
String incomingMethod = request.method();
|
||||
|
||||
incomingUrl = removeHost(incomingUrl);
|
||||
NetworkCallRecord networkCallRecord = null;
|
||||
synchronized (recordedData) {
|
||||
for (Iterator<NetworkCallRecord> iterator = recordedData.getNetworkCallRecords().iterator(); iterator.hasNext(); ) {
|
||||
NetworkCallRecord record = iterator.next();
|
||||
if (record.Method.equalsIgnoreCase(incomingMethod) && removeHost(record.Uri).equalsIgnoreCase(incomingUrl)) {
|
||||
networkCallRecord = record;
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (networkCallRecord == null) {
|
||||
System.out.println("NOT FOUND - " + incomingMethod + " " + incomingUrl);
|
||||
System.out.println("Remaining records " + recordedData.getNetworkCallRecords().size());
|
||||
throw new IOException("==> Unexpected request: " + incomingMethod + " " + incomingUrl);
|
||||
}
|
||||
|
||||
int recordStatusCode = Integer.parseInt(networkCallRecord.Response.get("StatusCode"));
|
||||
|
||||
//Response originalResponse = chain.proceed(request);
|
||||
//originalResponse.body().close();
|
||||
|
||||
Response.Builder responseBuilder = new Response.Builder()
|
||||
.request(request.newBuilder().build())
|
||||
.protocol(Protocol.HTTP_2)
|
||||
.code(recordStatusCode).message("-");
|
||||
|
||||
for (Map.Entry<String, String> pair : networkCallRecord.Response.entrySet()) {
|
||||
if (!pair.getKey().equals("StatusCode") && !pair.getKey().equals("Body") && !pair.getKey().equals("Content-Length")) {
|
||||
String rawHeader = pair.getValue();
|
||||
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
|
||||
if (rule.getValue() != null) {
|
||||
rawHeader = rawHeader.replaceAll(rule.getKey(), rule.getValue());
|
||||
}
|
||||
}
|
||||
responseBuilder.addHeader(pair.getKey(), rawHeader);
|
||||
}
|
||||
}
|
||||
|
||||
String rawBody = networkCallRecord.Response.get("Body");
|
||||
if (rawBody != null) {
|
||||
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
|
||||
if (rule.getValue() != null) {
|
||||
rawBody = rawBody.replaceAll(rule.getKey(), rule.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
String rawContentType = networkCallRecord.Response.get("content-type");
|
||||
String contentType = rawContentType == null
|
||||
? "application/json; charset=utf-8"
|
||||
: rawContentType;
|
||||
|
||||
ResponseBody responseBody;
|
||||
|
||||
if (contentType.toLowerCase().contains("application/json")) {
|
||||
responseBody = ResponseBody.create(MediaType.parse(contentType), rawBody.getBytes());
|
||||
} else {
|
||||
responseBody = ResponseBody.create(MediaType.parse(contentType), BaseEncoding.base64().decode(rawBody));
|
||||
}
|
||||
|
||||
responseBuilder.body(responseBody);
|
||||
responseBuilder.addHeader("Content-Length", String.valueOf(rawBody.getBytes("UTF-8").length));
|
||||
}
|
||||
|
||||
Response newResponse = responseBuilder.build();
|
||||
|
||||
return newResponse;
|
||||
}
|
||||
|
||||
private void extractResponseData(Map<String, String> responseData, Response response) throws IOException {
|
||||
Map<String, List<String>> headers = response.headers().toMultimap();
|
||||
boolean addedRetryAfter = false;
|
||||
for (Map.Entry<String, List<String>> header : headers.entrySet()) {
|
||||
String headerValueToStore = header.getValue().get(0);
|
||||
|
||||
if (header.getKey().equalsIgnoreCase("location") || header.getKey().equalsIgnoreCase("azure-asyncoperation")) {
|
||||
headerValueToStore = applyReplacementRule(headerValueToStore);
|
||||
}
|
||||
if (header.getKey().equalsIgnoreCase("retry-after")) {
|
||||
headerValueToStore = "0";
|
||||
addedRetryAfter = true;
|
||||
}
|
||||
responseData.put(header.getKey().toLowerCase(), headerValueToStore);
|
||||
}
|
||||
|
||||
if (!addedRetryAfter) {
|
||||
responseData.put("retry-after", "0");
|
||||
}
|
||||
|
||||
BufferedSource bufferedSource = response.body().source();
|
||||
bufferedSource.request(9223372036854775807L);
|
||||
Buffer buffer = bufferedSource.buffer().clone();
|
||||
String content = null;
|
||||
|
||||
if (response.header("Content-Encoding") == null) {
|
||||
String contentType = response.header("Content-Type");
|
||||
if (contentType != null) {
|
||||
if (contentType.startsWith("application/json"))
|
||||
{
|
||||
content = buffer.readString(Util.UTF_8);
|
||||
} else {
|
||||
content = BaseEncoding.base64().encode(buffer.readByteArray());
|
||||
}
|
||||
}
|
||||
} else if (response.header("Content-Encoding").equalsIgnoreCase("gzip")) {
|
||||
GZIPInputStream gis = new GZIPInputStream(buffer.inputStream());
|
||||
content = "";
|
||||
responseData.remove("Content-Encoding".toLowerCase());
|
||||
responseData.put("Content-Length".toLowerCase(), Integer.toString(content.length()));
|
||||
}
|
||||
|
||||
if (content != null) {
|
||||
content = applyReplacementRule(content);
|
||||
responseData.put("Body", content);
|
||||
}
|
||||
}
|
||||
|
||||
private void readDataFromFile() throws IOException {
|
||||
File recordFile = getRecordFile(testName);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
recordedData = mapper.readValue(recordFile, RecordedData.class);
|
||||
System.out.println("Total records " + recordedData.getNetworkCallRecords().size());
|
||||
}
|
||||
|
||||
private void writeDataToFile() throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
File recordFile = getRecordFile(testName);
|
||||
recordFile.createNewFile();
|
||||
mapper.writeValue(recordFile, recordedData);
|
||||
}
|
||||
|
||||
private File getRecordFile(String testName) {
|
||||
URL folderUrl = InterceptorManager.class.getClassLoader().getResource(".");
|
||||
File folderFile = new File(folderUrl.getPath() + RECORD_FOLDER);
|
||||
if (!folderFile.exists()) {
|
||||
folderFile.mkdir();
|
||||
}
|
||||
String filePath = folderFile.getPath() + "/" + testName + ".json";
|
||||
System.out.println("==> Playback file path: " + filePath);
|
||||
return new File(filePath);
|
||||
}
|
||||
|
||||
private String applyReplacementRule(String text) {
|
||||
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
|
||||
if (rule.getValue() != null) {
|
||||
text = text.replaceAll(rule.getKey(), rule.getValue());
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private String removeHost(String url) {
|
||||
URI uri = URI.create(url);
|
||||
return String.format("%s?%s", uri.getPath(), uri.getQuery());
|
||||
}
|
||||
|
||||
public void pushVariable(String variable) {
|
||||
if (isRecordMode()) {
|
||||
synchronized (recordedData.getVariables()) {
|
||||
recordedData.getVariables().add(variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String popVariable() {
|
||||
synchronized (recordedData.getVariables()) {
|
||||
return recordedData.getVariables().remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import okhttp3.*;
|
||||
import okhttp3.internal.Util;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class InterceptorManager {
|
||||
|
||||
private final static String RECORD_FOLDER = "session-records/";
|
||||
|
||||
private Map<String, String> textReplacementRules = new HashMap<String, String>();
|
||||
// Stores a map of all the HTTP properties in a session
|
||||
// A state machine ensuring a test is always reset before another one is setup
|
||||
|
||||
protected RecordedData recordedData;
|
||||
|
||||
private final String testName;
|
||||
|
||||
private final TestBase.TestMode testMode;
|
||||
|
||||
private InterceptorManager(String testName, TestBase.TestMode testMode) {
|
||||
this.testName = testName;
|
||||
this.testMode = testMode;
|
||||
}
|
||||
|
||||
public void addTextReplacementRule(String regex, String replacement) {
|
||||
textReplacementRules.put(regex, replacement);
|
||||
}
|
||||
|
||||
// factory method
|
||||
public static InterceptorManager create(String testName, TestBase.TestMode testMode) throws IOException {
|
||||
InterceptorManager interceptorManager = new InterceptorManager(testName, testMode);
|
||||
|
||||
return interceptorManager;
|
||||
}
|
||||
|
||||
public boolean isRecordMode() {
|
||||
return testMode == TestBase.TestMode.RECORD;
|
||||
}
|
||||
|
||||
public boolean isPlaybackMode() {
|
||||
return testMode == TestBase.TestMode.PLAYBACK;
|
||||
}
|
||||
|
||||
public Interceptor initInterceptor() throws IOException {
|
||||
switch (testMode) {
|
||||
case RECORD:
|
||||
recordedData = new RecordedData();
|
||||
return new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return record(chain);
|
||||
}
|
||||
};
|
||||
case PLAYBACK:
|
||||
readDataFromFile();
|
||||
return new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
return playback(chain);
|
||||
}
|
||||
};
|
||||
default:
|
||||
System.out.println("==> Unknown AZURE_TEST_MODE: " + testMode);
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
public void finalizeInterceptor() throws IOException {
|
||||
switch (testMode) {
|
||||
case RECORD:
|
||||
writeDataToFile();
|
||||
break;
|
||||
case PLAYBACK:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
System.out.println("==> Unknown AZURE_TEST_MODE: " + testMode);
|
||||
};
|
||||
}
|
||||
|
||||
private Response record(Interceptor.Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
NetworkCallRecord networkCallRecord = new NetworkCallRecord();
|
||||
|
||||
networkCallRecord.Headers = new HashMap<>();
|
||||
|
||||
if (request.header("Content-Type") != null) {
|
||||
networkCallRecord.Headers.put("Content-Type", request.header("Content-Type"));
|
||||
}
|
||||
if (request.header("x-ms-version") != null) {
|
||||
networkCallRecord.Headers.put("x-ms-version", request.header("x-ms-version"));
|
||||
}
|
||||
if (request.header("User-Agent") != null) {
|
||||
networkCallRecord.Headers.put("User-Agent", request.header("User-Agent"));
|
||||
}
|
||||
|
||||
networkCallRecord.Method = request.method();
|
||||
networkCallRecord.Uri = applyReplacementRule(request.url().toString().replaceAll("\\?$", ""));
|
||||
|
||||
networkCallRecord.Body = bodyToString(request);
|
||||
|
||||
Response response = chain.proceed(request);
|
||||
|
||||
networkCallRecord.Response = new HashMap<>();
|
||||
networkCallRecord.Response.put("StatusCode", Integer.toString(response.code()));
|
||||
extractResponseData(networkCallRecord.Response, response);
|
||||
|
||||
// remove pre-added header if this is a waiting or redirection
|
||||
if (networkCallRecord.Response.get("Body") != null) {
|
||||
if (networkCallRecord.Response.get("Body").contains("<Status>InProgress</Status>")
|
||||
|| Integer.parseInt(networkCallRecord.Response.get("StatusCode")) == 307) {
|
||||
// Do nothing
|
||||
} else {
|
||||
synchronized (recordedData.getNetworkCallRecords()) {
|
||||
recordedData.getNetworkCallRecords().add(networkCallRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private String bodyToString(final Request request) {
|
||||
try {
|
||||
final Buffer buffer = new Buffer();
|
||||
|
||||
request.newBuilder().build().body().writeTo(buffer);
|
||||
return buffer.readUtf8();
|
||||
} catch (final Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private Response playback(Interceptor.Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
String incomingUrl = applyReplacementRule(request.url().toString());
|
||||
String incomingMethod = request.method();
|
||||
|
||||
incomingUrl = removeHost(incomingUrl);
|
||||
NetworkCallRecord networkCallRecord = null;
|
||||
synchronized (recordedData) {
|
||||
for (Iterator<NetworkCallRecord> iterator = recordedData.getNetworkCallRecords().iterator(); iterator.hasNext(); ) {
|
||||
NetworkCallRecord record = iterator.next();
|
||||
if (record.Method.equalsIgnoreCase(incomingMethod) && removeHost(record.Uri).equalsIgnoreCase(incomingUrl)) {
|
||||
networkCallRecord = record;
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (networkCallRecord == null) {
|
||||
System.out.println("NOT FOUND - " + incomingMethod + " " + incomingUrl);
|
||||
System.out.println("Remaining records " + recordedData.getNetworkCallRecords().size());
|
||||
throw new IOException("==> Unexpected request: " + incomingMethod + " " + incomingUrl);
|
||||
}
|
||||
|
||||
int recordStatusCode = Integer.parseInt(networkCallRecord.Response.get("StatusCode"));
|
||||
|
||||
//Response originalResponse = chain.proceed(request);
|
||||
//originalResponse.body().close();
|
||||
|
||||
Response.Builder responseBuilder = new Response.Builder()
|
||||
.request(request.newBuilder().build())
|
||||
.protocol(Protocol.HTTP_2)
|
||||
.code(recordStatusCode).message("-");
|
||||
|
||||
for (Map.Entry<String, String> pair : networkCallRecord.Response.entrySet()) {
|
||||
if (!pair.getKey().equals("StatusCode") && !pair.getKey().equals("Body") && !pair.getKey().equals("Content-Length")) {
|
||||
String rawHeader = pair.getValue();
|
||||
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
|
||||
if (rule.getValue() != null) {
|
||||
rawHeader = rawHeader.replaceAll(rule.getKey(), rule.getValue());
|
||||
}
|
||||
}
|
||||
responseBuilder.addHeader(pair.getKey(), rawHeader);
|
||||
}
|
||||
}
|
||||
|
||||
String rawBody = networkCallRecord.Response.get("Body");
|
||||
if (rawBody != null) {
|
||||
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
|
||||
if (rule.getValue() != null) {
|
||||
rawBody = rawBody.replaceAll(rule.getKey(), rule.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
String rawContentType = networkCallRecord.Response.get("content-type");
|
||||
String contentType = rawContentType == null
|
||||
? "application/json; charset=utf-8"
|
||||
: rawContentType;
|
||||
|
||||
ResponseBody responseBody;
|
||||
|
||||
if (contentType.toLowerCase().contains("application/json")) {
|
||||
responseBody = ResponseBody.create(MediaType.parse(contentType), rawBody.getBytes());
|
||||
} else {
|
||||
responseBody = ResponseBody.create(MediaType.parse(contentType), BaseEncoding.base64().decode(rawBody));
|
||||
}
|
||||
|
||||
responseBuilder.body(responseBody);
|
||||
responseBuilder.addHeader("Content-Length", String.valueOf(rawBody.getBytes("UTF-8").length));
|
||||
}
|
||||
|
||||
Response newResponse = responseBuilder.build();
|
||||
|
||||
return newResponse;
|
||||
}
|
||||
|
||||
private void extractResponseData(Map<String, String> responseData, Response response) throws IOException {
|
||||
Map<String, List<String>> headers = response.headers().toMultimap();
|
||||
boolean addedRetryAfter = false;
|
||||
for (Map.Entry<String, List<String>> header : headers.entrySet()) {
|
||||
String headerValueToStore = header.getValue().get(0);
|
||||
|
||||
if (header.getKey().equalsIgnoreCase("location") || header.getKey().equalsIgnoreCase("azure-asyncoperation")) {
|
||||
headerValueToStore = applyReplacementRule(headerValueToStore);
|
||||
}
|
||||
if (header.getKey().equalsIgnoreCase("retry-after")) {
|
||||
headerValueToStore = "0";
|
||||
addedRetryAfter = true;
|
||||
}
|
||||
responseData.put(header.getKey().toLowerCase(), headerValueToStore);
|
||||
}
|
||||
|
||||
if (!addedRetryAfter) {
|
||||
responseData.put("retry-after", "0");
|
||||
}
|
||||
|
||||
BufferedSource bufferedSource = response.body().source();
|
||||
bufferedSource.request(9223372036854775807L);
|
||||
Buffer buffer = bufferedSource.buffer().clone();
|
||||
String content = null;
|
||||
|
||||
if (response.header("Content-Encoding") == null) {
|
||||
String contentType = response.header("Content-Type");
|
||||
if (contentType != null) {
|
||||
if (contentType.startsWith("application/json"))
|
||||
{
|
||||
content = buffer.readString(Util.UTF_8);
|
||||
} else {
|
||||
content = BaseEncoding.base64().encode(buffer.readByteArray());
|
||||
}
|
||||
}
|
||||
} else if (response.header("Content-Encoding").equalsIgnoreCase("gzip")) {
|
||||
GZIPInputStream gis = new GZIPInputStream(buffer.inputStream());
|
||||
content = "";
|
||||
responseData.remove("Content-Encoding".toLowerCase());
|
||||
responseData.put("Content-Length".toLowerCase(), Integer.toString(content.length()));
|
||||
}
|
||||
|
||||
if (content != null) {
|
||||
content = applyReplacementRule(content);
|
||||
responseData.put("Body", content);
|
||||
}
|
||||
}
|
||||
|
||||
private void readDataFromFile() throws IOException {
|
||||
File recordFile = getRecordFile(testName);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
recordedData = mapper.readValue(recordFile, RecordedData.class);
|
||||
System.out.println("Total records " + recordedData.getNetworkCallRecords().size());
|
||||
}
|
||||
|
||||
private void writeDataToFile() throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
File recordFile = getRecordFile(testName);
|
||||
recordFile.createNewFile();
|
||||
mapper.writeValue(recordFile, recordedData);
|
||||
}
|
||||
|
||||
private File getRecordFile(String testName) {
|
||||
URL folderUrl = InterceptorManager.class.getClassLoader().getResource(".");
|
||||
File folderFile = new File(folderUrl.getPath() + RECORD_FOLDER);
|
||||
if (!folderFile.exists()) {
|
||||
folderFile.mkdir();
|
||||
}
|
||||
String filePath = folderFile.getPath() + "/" + testName + ".json";
|
||||
System.out.println("==> Playback file path: " + filePath);
|
||||
return new File(filePath);
|
||||
}
|
||||
|
||||
private String applyReplacementRule(String text) {
|
||||
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
|
||||
if (rule.getValue() != null) {
|
||||
text = text.replaceAll(rule.getKey(), rule.getValue());
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private String removeHost(String url) {
|
||||
URI uri = URI.create(url);
|
||||
return String.format("%s?%s", uri.getPath(), uri.getQuery());
|
||||
}
|
||||
|
||||
public void pushVariable(String variable) {
|
||||
if (isRecordMode()) {
|
||||
synchronized (recordedData.getVariables()) {
|
||||
recordedData.getVariables().add(variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String popVariable() {
|
||||
synchronized (recordedData.getVariables()) {
|
||||
return recordedData.getVariables().remove();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class NetworkCallRecord {
|
||||
public String Method;
|
||||
public String Uri;
|
||||
public String Body;
|
||||
|
||||
public Map<String, String> Headers;
|
||||
public Map<String, String> Response;
|
||||
}
|
||||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class NetworkCallRecord {
|
||||
public String Method;
|
||||
public String Uri;
|
||||
public String Body;
|
||||
|
||||
public Map<String, String> Headers;
|
||||
public Map<String, String> Response;
|
||||
}
|
|
@ -1,22 +1,22 @@
|
|||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class RecordedData {
|
||||
private LinkedList<NetworkCallRecord> networkCallRecords;
|
||||
|
||||
private LinkedList<String> variables;
|
||||
|
||||
public RecordedData() {
|
||||
networkCallRecords = new LinkedList<>();
|
||||
variables = new LinkedList<>();
|
||||
}
|
||||
|
||||
public LinkedList<NetworkCallRecord> getNetworkCallRecords() {
|
||||
return networkCallRecords;
|
||||
}
|
||||
|
||||
public LinkedList<String> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class RecordedData {
|
||||
private LinkedList<NetworkCallRecord> networkCallRecords;
|
||||
|
||||
private LinkedList<String> variables;
|
||||
|
||||
public RecordedData() {
|
||||
networkCallRecords = new LinkedList<>();
|
||||
variables = new LinkedList<>();
|
||||
}
|
||||
|
||||
public LinkedList<NetworkCallRecord> getNetworkCallRecords() {
|
||||
return networkCallRecords;
|
||||
}
|
||||
|
||||
public LinkedList<String> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
}
|
|
@ -1,212 +1,212 @@
|
|||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials;
|
||||
import com.microsoft.rest.LogLevel;
|
||||
import com.microsoft.rest.RestClient;
|
||||
import com.microsoft.rest.ServiceResponseBuilder;
|
||||
import com.microsoft.rest.credentials.ServiceClientCredentials;
|
||||
import com.microsoft.rest.credentials.TokenCredentials;
|
||||
import com.microsoft.rest.interceptors.LoggingInterceptor;
|
||||
import com.microsoft.rest.serializer.JacksonAdapter;
|
||||
import org.junit.*;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class TestBase {
|
||||
|
||||
private PrintStream out;
|
||||
|
||||
protected enum RunCondition {
|
||||
MOCK_ONLY,
|
||||
LIVE_ONLY,
|
||||
BOTH
|
||||
}
|
||||
|
||||
public enum TestMode {
|
||||
PLAYBACK,
|
||||
RECORD
|
||||
}
|
||||
|
||||
private final RunCondition runCondition;
|
||||
|
||||
protected TestBase() {
|
||||
this(RunCondition.BOTH);
|
||||
}
|
||||
|
||||
protected TestBase(RunCondition runCondition) {
|
||||
this.runCondition = runCondition;
|
||||
}
|
||||
|
||||
private String shouldCancelTest(boolean isPlaybackMode) {
|
||||
// Determine whether to run the test based on the condition the test has been configured with
|
||||
switch (this.runCondition) {
|
||||
case MOCK_ONLY:
|
||||
return (!isPlaybackMode) ? "Test configured to run only as mocked, not live." : null;
|
||||
case LIVE_ONLY:
|
||||
return (isPlaybackMode) ? "Test configured to run only as live, not mocked." : null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static TestMode testMode = null;
|
||||
|
||||
protected final static String ZERO_CLIENT_ID = "00000000-0000-0000-0000-000000000000";
|
||||
protected final static String ZERO_CLIENT_SECRET = "00000000000000000000000";
|
||||
protected final static String ZERO_USER_ID = "<--dummy-user-id-->";
|
||||
protected final static String ZERO_BOT_ID = "<--dummy-bot-id-->";
|
||||
protected final static String ZERO_TOKEN = "<--dummy-token-->";
|
||||
|
||||
private static final String PLAYBACK_URI = "http://localhost:1234";
|
||||
|
||||
protected static String hostUri = null;
|
||||
protected static String clientId = null;
|
||||
protected static String clientSecret = null;
|
||||
protected static String userId = null;
|
||||
protected static String botId = null;
|
||||
|
||||
private static void initTestMode() throws IOException {
|
||||
String azureTestMode = System.getenv("AZURE_TEST_MODE");
|
||||
if (azureTestMode != null) {
|
||||
if (azureTestMode.equalsIgnoreCase("Record")) {
|
||||
testMode = TestMode.RECORD;
|
||||
} else if (azureTestMode.equalsIgnoreCase("Playback")) {
|
||||
testMode = TestMode.PLAYBACK;
|
||||
} else {
|
||||
throw new IOException("Unknown AZURE_TEST_MODE: " + azureTestMode);
|
||||
}
|
||||
} else {
|
||||
System.out.print("Environment variable 'AZURE_TEST_MODE' has not been set yet. Using 'PLAYBACK' mode.");
|
||||
testMode = TestMode.RECORD;
|
||||
}
|
||||
}
|
||||
|
||||
private static void initParams() {
|
||||
try {
|
||||
Properties mavenProps = new Properties();
|
||||
InputStream in = TestBase.class.getResourceAsStream("/maven.properties");
|
||||
if (in == null) {
|
||||
throw new IOException("The file \"maven.properties\" has not been generated yet. Please execute \"mvn compile\" to generate the file.");
|
||||
}
|
||||
mavenProps.load(in);
|
||||
|
||||
clientId = mavenProps.getProperty("clientId");
|
||||
clientSecret = mavenProps.getProperty("clientSecret");
|
||||
hostUri = mavenProps.getProperty("hostUrl");
|
||||
userId = mavenProps.getProperty("userId");
|
||||
botId = mavenProps.getProperty("botId");
|
||||
} catch (IOException e) {
|
||||
clientId = ZERO_CLIENT_ID;
|
||||
clientSecret = ZERO_CLIENT_SECRET;
|
||||
hostUri = PLAYBACK_URI;
|
||||
userId = ZERO_USER_ID;
|
||||
botId = ZERO_BOT_ID;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPlaybackMode() {
|
||||
if (testMode == null) try {
|
||||
initTestMode();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Can't init test mode.");
|
||||
}
|
||||
return testMode == TestMode.PLAYBACK;
|
||||
}
|
||||
|
||||
public static boolean isRecordMode() {
|
||||
return !isPlaybackMode();
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestName testName = new TestName();
|
||||
|
||||
protected InterceptorManager interceptorManager = null;
|
||||
|
||||
private static void printThreadInfo(String what) {
|
||||
long id = Thread.currentThread().getId();
|
||||
String name = Thread.currentThread().getName();
|
||||
System.out.println(String.format("\n***\n*** [%s:%s] - %s\n***\n", name, id, what));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws IOException {
|
||||
printThreadInfo("beforeClass");
|
||||
initTestMode();
|
||||
initParams();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws IOException {
|
||||
printThreadInfo(String.format("%s: %s", "beforeTest", testName.getMethodName()));
|
||||
final String skipMessage = shouldCancelTest(isPlaybackMode());
|
||||
Assume.assumeTrue(skipMessage, skipMessage == null);
|
||||
|
||||
interceptorManager = InterceptorManager.create(testName.getMethodName(), testMode);
|
||||
|
||||
ServiceClientCredentials credentials;
|
||||
RestClient restClient;
|
||||
|
||||
if (isPlaybackMode()) {
|
||||
credentials = new TokenCredentials(null, ZERO_TOKEN);
|
||||
restClient = buildRestClient(new RestClient.Builder()
|
||||
.withBaseUrl(hostUri + "/")
|
||||
.withSerializerAdapter(new JacksonAdapter())
|
||||
.withResponseBuilderFactory(new ServiceResponseBuilder.Factory())
|
||||
.withCredentials(credentials)
|
||||
.withLogLevel(LogLevel.NONE)
|
||||
.withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS))
|
||||
.withInterceptor(interceptorManager.initInterceptor())
|
||||
,true);
|
||||
|
||||
out = System.out;
|
||||
System.setOut(new PrintStream(new OutputStream() {
|
||||
public void write(int b) {
|
||||
//DO NOTHING
|
||||
}
|
||||
}));
|
||||
}
|
||||
else { // Record mode
|
||||
credentials = new MicrosoftAppCredentials(clientId, clientSecret);
|
||||
restClient = buildRestClient(new RestClient.Builder()
|
||||
.withBaseUrl(hostUri + "/")
|
||||
.withSerializerAdapter(new JacksonAdapter())
|
||||
.withResponseBuilderFactory(new ServiceResponseBuilder.Factory())
|
||||
.withCredentials(credentials)
|
||||
.withLogLevel(LogLevel.NONE)
|
||||
.withReadTimeout(3, TimeUnit.MINUTES)
|
||||
.withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS))
|
||||
.withInterceptor(interceptorManager.initInterceptor())
|
||||
,false);
|
||||
|
||||
//interceptorManager.addTextReplacementRule(hostUri, PLAYBACK_URI);
|
||||
}
|
||||
initializeClients(restClient, botId, userId);
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterTest() throws IOException {
|
||||
if(shouldCancelTest(isPlaybackMode()) != null) {
|
||||
return;
|
||||
}
|
||||
cleanUpResources();
|
||||
interceptorManager.finalizeInterceptor();
|
||||
}
|
||||
|
||||
protected void addTextReplacementRule(String from, String to ) {
|
||||
interceptorManager.addTextReplacementRule(from, to);
|
||||
}
|
||||
|
||||
protected RestClient buildRestClient(RestClient.Builder builder, boolean isMocked) {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected abstract void initializeClients(RestClient restClient, String botId, String userId) throws IOException;
|
||||
protected abstract void cleanUpResources();
|
||||
}
|
||||
package com.microsoft.bot.builder.base;
|
||||
|
||||
import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials;
|
||||
import com.microsoft.rest.LogLevel;
|
||||
import com.microsoft.rest.RestClient;
|
||||
import com.microsoft.rest.ServiceResponseBuilder;
|
||||
import com.microsoft.rest.credentials.ServiceClientCredentials;
|
||||
import com.microsoft.rest.credentials.TokenCredentials;
|
||||
import com.microsoft.rest.interceptors.LoggingInterceptor;
|
||||
import com.microsoft.rest.serializer.JacksonAdapter;
|
||||
import org.junit.*;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class TestBase {
|
||||
|
||||
private PrintStream out;
|
||||
|
||||
protected enum RunCondition {
|
||||
MOCK_ONLY,
|
||||
LIVE_ONLY,
|
||||
BOTH
|
||||
}
|
||||
|
||||
public enum TestMode {
|
||||
PLAYBACK,
|
||||
RECORD
|
||||
}
|
||||
|
||||
private final RunCondition runCondition;
|
||||
|
||||
protected TestBase() {
|
||||
this(RunCondition.BOTH);
|
||||
}
|
||||
|
||||
protected TestBase(RunCondition runCondition) {
|
||||
this.runCondition = runCondition;
|
||||
}
|
||||
|
||||
private String shouldCancelTest(boolean isPlaybackMode) {
|
||||
// Determine whether to run the test based on the condition the test has been configured with
|
||||
switch (this.runCondition) {
|
||||
case MOCK_ONLY:
|
||||
return (!isPlaybackMode) ? "Test configured to run only as mocked, not live." : null;
|
||||
case LIVE_ONLY:
|
||||
return (isPlaybackMode) ? "Test configured to run only as live, not mocked." : null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static TestMode testMode = null;
|
||||
|
||||
protected final static String ZERO_CLIENT_ID = "00000000-0000-0000-0000-000000000000";
|
||||
protected final static String ZERO_CLIENT_SECRET = "00000000000000000000000";
|
||||
protected final static String ZERO_USER_ID = "<--dummy-user-id-->";
|
||||
protected final static String ZERO_BOT_ID = "<--dummy-bot-id-->";
|
||||
protected final static String ZERO_TOKEN = "<--dummy-token-->";
|
||||
|
||||
private static final String PLAYBACK_URI = "http://localhost:1234";
|
||||
|
||||
protected static String hostUri = null;
|
||||
protected static String clientId = null;
|
||||
protected static String clientSecret = null;
|
||||
protected static String userId = null;
|
||||
protected static String botId = null;
|
||||
|
||||
private static void initTestMode() throws IOException {
|
||||
String azureTestMode = System.getenv("AZURE_TEST_MODE");
|
||||
if (azureTestMode != null) {
|
||||
if (azureTestMode.equalsIgnoreCase("Record")) {
|
||||
testMode = TestMode.RECORD;
|
||||
} else if (azureTestMode.equalsIgnoreCase("Playback")) {
|
||||
testMode = TestMode.PLAYBACK;
|
||||
} else {
|
||||
throw new IOException("Unknown AZURE_TEST_MODE: " + azureTestMode);
|
||||
}
|
||||
} else {
|
||||
System.out.print("Environment variable 'AZURE_TEST_MODE' has not been set yet. Using 'PLAYBACK' mode.");
|
||||
testMode = TestMode.RECORD;
|
||||
}
|
||||
}
|
||||
|
||||
private static void initParams() {
|
||||
try {
|
||||
Properties mavenProps = new Properties();
|
||||
InputStream in = TestBase.class.getResourceAsStream("/maven.properties");
|
||||
if (in == null) {
|
||||
throw new IOException("The file \"maven.properties\" has not been generated yet. Please execute \"mvn compile\" to generate the file.");
|
||||
}
|
||||
mavenProps.load(in);
|
||||
|
||||
clientId = mavenProps.getProperty("clientId");
|
||||
clientSecret = mavenProps.getProperty("clientSecret");
|
||||
hostUri = mavenProps.getProperty("hostUrl");
|
||||
userId = mavenProps.getProperty("userId");
|
||||
botId = mavenProps.getProperty("botId");
|
||||
} catch (IOException e) {
|
||||
clientId = ZERO_CLIENT_ID;
|
||||
clientSecret = ZERO_CLIENT_SECRET;
|
||||
hostUri = PLAYBACK_URI;
|
||||
userId = ZERO_USER_ID;
|
||||
botId = ZERO_BOT_ID;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPlaybackMode() {
|
||||
if (testMode == null) try {
|
||||
initTestMode();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Can't init test mode.");
|
||||
}
|
||||
return testMode == TestMode.PLAYBACK;
|
||||
}
|
||||
|
||||
public static boolean isRecordMode() {
|
||||
return !isPlaybackMode();
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestName testName = new TestName();
|
||||
|
||||
protected InterceptorManager interceptorManager = null;
|
||||
|
||||
private static void printThreadInfo(String what) {
|
||||
long id = Thread.currentThread().getId();
|
||||
String name = Thread.currentThread().getName();
|
||||
System.out.println(String.format("\n***\n*** [%s:%s] - %s\n***\n", name, id, what));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws IOException {
|
||||
printThreadInfo("beforeClass");
|
||||
initTestMode();
|
||||
initParams();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws IOException {
|
||||
printThreadInfo(String.format("%s: %s", "beforeTest", testName.getMethodName()));
|
||||
final String skipMessage = shouldCancelTest(isPlaybackMode());
|
||||
Assume.assumeTrue(skipMessage, skipMessage == null);
|
||||
|
||||
interceptorManager = InterceptorManager.create(testName.getMethodName(), testMode);
|
||||
|
||||
ServiceClientCredentials credentials;
|
||||
RestClient restClient;
|
||||
|
||||
if (isPlaybackMode()) {
|
||||
credentials = new TokenCredentials(null, ZERO_TOKEN);
|
||||
restClient = buildRestClient(new RestClient.Builder()
|
||||
.withBaseUrl(hostUri + "/")
|
||||
.withSerializerAdapter(new JacksonAdapter())
|
||||
.withResponseBuilderFactory(new ServiceResponseBuilder.Factory())
|
||||
.withCredentials(credentials)
|
||||
.withLogLevel(LogLevel.NONE)
|
||||
.withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS))
|
||||
.withInterceptor(interceptorManager.initInterceptor())
|
||||
,true);
|
||||
|
||||
out = System.out;
|
||||
System.setOut(new PrintStream(new OutputStream() {
|
||||
public void write(int b) {
|
||||
//DO NOTHING
|
||||
}
|
||||
}));
|
||||
}
|
||||
else { // Record mode
|
||||
credentials = new MicrosoftAppCredentials(clientId, clientSecret);
|
||||
restClient = buildRestClient(new RestClient.Builder()
|
||||
.withBaseUrl(hostUri + "/")
|
||||
.withSerializerAdapter(new JacksonAdapter())
|
||||
.withResponseBuilderFactory(new ServiceResponseBuilder.Factory())
|
||||
.withCredentials(credentials)
|
||||
.withLogLevel(LogLevel.NONE)
|
||||
.withReadTimeout(3, TimeUnit.MINUTES)
|
||||
.withNetworkInterceptor(new LoggingInterceptor(LogLevel.BODY_AND_HEADERS))
|
||||
.withInterceptor(interceptorManager.initInterceptor())
|
||||
,false);
|
||||
|
||||
//interceptorManager.addTextReplacementRule(hostUri, PLAYBACK_URI);
|
||||
}
|
||||
initializeClients(restClient, botId, userId);
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterTest() throws IOException {
|
||||
if(shouldCancelTest(isPlaybackMode()) != null) {
|
||||
return;
|
||||
}
|
||||
cleanUpResources();
|
||||
interceptorManager.finalizeInterceptor();
|
||||
}
|
||||
|
||||
protected void addTextReplacementRule(String from, String to ) {
|
||||
interceptorManager.addTextReplacementRule(from, to);
|
||||
}
|
||||
|
||||
protected RestClient buildRestClient(RestClient.Builder builder, boolean isMocked) {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected abstract void initializeClients(RestClient restClient, String botId, String userId) throws IOException;
|
||||
protected abstract void cleanUpResources();
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.microsoft.bot.connector</groupId>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-connector</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
|
@ -87,8 +87,8 @@
|
|||
<version>0.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.bot.schema</groupId>
|
||||
<artifactId>botbuilder-schema</artifactId>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-schema</artifactId>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.microsoft.bot.schema</groupId>
|
||||
<artifactId>botbuilder-schema</artifactId>
|
||||
<groupId>com.microsoft.bot</groupId>
|
||||
<artifactId>bot-schema</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
|
||||
|
@ -118,7 +118,7 @@
|
|||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<configuration>
|
||||
<outputDirectory>../../cobertura-report/botbuilder-schema</outputDirectory>
|
||||
<outputDirectory>../../cobertura-report/bot-schema</outputDirectory>
|
||||
<format>xml</format>
|
||||
<maxmem>256m</maxmem>
|
||||
<!-- aggregated reports for multi-module projects -->
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,18 +1,18 @@
|
|||
package com.microsoft.bot.schema;
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
|
||||
public class ContactRelationUpdateActivity extends Activity {
|
||||
/**
|
||||
* add|remove
|
||||
*/
|
||||
private String _action;
|
||||
|
||||
public String getAction() {
|
||||
return _action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this._action = action;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.schema;
|
||||
|
||||
import com.microsoft.bot.schema.models.Activity;
|
||||
|
||||
public class ContactRelationUpdateActivity extends Activity {
|
||||
/**
|
||||
* add|remove
|
||||
*/
|
||||
private String _action;
|
||||
|
||||
public String getAction() {
|
||||
return _action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this._action = action;
|
||||
}
|
||||
}
|
|
@ -1,146 +1,146 @@
|
|||
package com.microsoft.bot.schema;
|
||||
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.microsoft.bot.schema.models.Entity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
public class EntityImpl extends Entity {
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the Entity class.
|
||||
*/
|
||||
public EntityImpl() {
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the Entity class.
|
||||
* @param type Entity Type (typically from schema.org
|
||||
* types)
|
||||
*/
|
||||
public EntityImpl(String type) {
|
||||
this.type = type;
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* An initialization method that performs custom operations like setting defaults
|
||||
*/
|
||||
void CustomInit() {
|
||||
}
|
||||
/**
|
||||
* Gets or sets entity Type (typically from schema.org types)
|
||||
*/
|
||||
public String type;
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> properties() {
|
||||
|
||||
return this.properties;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve internal payload.
|
||||
*/
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param T
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
||||
public <T> T GetAs(Class<T> type) {
|
||||
|
||||
// Serialize
|
||||
String tempJson;
|
||||
try {
|
||||
tempJson = objectMapper.writeValueAsString(this);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
// Deserialize
|
||||
T newObj = null;
|
||||
try {
|
||||
newObj = (T) objectMapper.readValue(tempJson, type);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return newObj;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set internal payload.
|
||||
* @param T
|
||||
* @param obj
|
||||
*/
|
||||
|
||||
public <T> boolean SetAs(T obj) {
|
||||
// Serialize
|
||||
String tempJson;
|
||||
try {
|
||||
tempJson = objectMapper.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
EntityImpl tempEntity;
|
||||
try {
|
||||
tempEntity = objectMapper.readValue(tempJson, EntityImpl.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, JsonNode> entry : tempEntity.properties.entrySet()) {
|
||||
this.properties.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
this.type = obj.getClass().getTypeName();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
package com.microsoft.bot.schema;
|
||||
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.microsoft.bot.schema.models.Entity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
public class EntityImpl extends Entity {
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the Entity class.
|
||||
*/
|
||||
public EntityImpl() {
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the Entity class.
|
||||
* @param type Entity Type (typically from schema.org
|
||||
* types)
|
||||
*/
|
||||
public EntityImpl(String type) {
|
||||
this.type = type;
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* An initialization method that performs custom operations like setting defaults
|
||||
*/
|
||||
void CustomInit() {
|
||||
}
|
||||
/**
|
||||
* Gets or sets entity Type (typically from schema.org types)
|
||||
*/
|
||||
public String type;
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> properties() {
|
||||
|
||||
return this.properties;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve internal payload.
|
||||
*/
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param T
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
||||
public <T> T GetAs(Class<T> type) {
|
||||
|
||||
// Serialize
|
||||
String tempJson;
|
||||
try {
|
||||
tempJson = objectMapper.writeValueAsString(this);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
// Deserialize
|
||||
T newObj = null;
|
||||
try {
|
||||
newObj = (T) objectMapper.readValue(tempJson, type);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return newObj;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set internal payload.
|
||||
* @param T
|
||||
* @param obj
|
||||
*/
|
||||
|
||||
public <T> boolean SetAs(T obj) {
|
||||
// Serialize
|
||||
String tempJson;
|
||||
try {
|
||||
tempJson = objectMapper.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
EntityImpl tempEntity;
|
||||
try {
|
||||
tempEntity = objectMapper.readValue(tempJson, EntityImpl.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, JsonNode> entry : tempEntity.properties.entrySet()) {
|
||||
this.properties.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
this.type = obj.getClass().getTypeName();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package com.microsoft.bot.schema;
|
||||
|
||||
public class ResultPair<X, Y> {
|
||||
public final X x;
|
||||
public final Y y;
|
||||
public ResultPair(X x, Y y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.schema;
|
||||
|
||||
public class ResultPair<X, Y> {
|
||||
public final X x;
|
||||
public final Y y;
|
||||
public ResultPair(X x, Y y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
|
@ -1,62 +1,62 @@
|
|||
package com.microsoft.bot.schema;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
/**
|
||||
* State object passed to the bot token service.
|
||||
*/
|
||||
public class TokenExchangeState
|
||||
{
|
||||
/**
|
||||
* The connection name that was used
|
||||
*/
|
||||
@JsonProperty(value = "connectionName")
|
||||
private String connectionName;
|
||||
public String connectionName() {
|
||||
return this.connectionName;
|
||||
}
|
||||
public TokenExchangeState withConnectionName(String connectionName) {
|
||||
this.connectionName = connectionName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference to the conversation
|
||||
*/
|
||||
@JsonProperty(value = "conversation")
|
||||
private ConversationReference conversation;
|
||||
public ConversationReference conversation() {
|
||||
return this.conversation;
|
||||
}
|
||||
public TokenExchangeState withConversation(ConversationReference conversation) {
|
||||
this.conversation = conversation;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the bot messaging endpoint
|
||||
*/
|
||||
@JsonProperty("botUrl")
|
||||
private String botUrl;
|
||||
public String botUrl() {
|
||||
return this.botUrl;
|
||||
}
|
||||
public TokenExchangeState withBotUrl(String botUrl) {
|
||||
this.botUrl = botUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The bot's registered application ID
|
||||
*/
|
||||
@JsonProperty("msAppId")
|
||||
String msAppId;
|
||||
public String msAppId() {
|
||||
return this.msAppId;
|
||||
}
|
||||
public TokenExchangeState withMsAppId(String msAppId) {
|
||||
this.msAppId = msAppId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.schema;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
/**
|
||||
* State object passed to the bot token service.
|
||||
*/
|
||||
public class TokenExchangeState
|
||||
{
|
||||
/**
|
||||
* The connection name that was used
|
||||
*/
|
||||
@JsonProperty(value = "connectionName")
|
||||
private String connectionName;
|
||||
public String connectionName() {
|
||||
return this.connectionName;
|
||||
}
|
||||
public TokenExchangeState withConnectionName(String connectionName) {
|
||||
this.connectionName = connectionName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference to the conversation
|
||||
*/
|
||||
@JsonProperty(value = "conversation")
|
||||
private ConversationReference conversation;
|
||||
public ConversationReference conversation() {
|
||||
return this.conversation;
|
||||
}
|
||||
public TokenExchangeState withConversation(ConversationReference conversation) {
|
||||
this.conversation = conversation;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the bot messaging endpoint
|
||||
*/
|
||||
@JsonProperty("botUrl")
|
||||
private String botUrl;
|
||||
public String botUrl() {
|
||||
return this.botUrl;
|
||||
}
|
||||
public TokenExchangeState withBotUrl(String botUrl) {
|
||||
this.botUrl = botUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The bot's registered application ID
|
||||
*/
|
||||
@JsonProperty("msAppId")
|
||||
String msAppId;
|
||||
public String msAppId() {
|
||||
return this.msAppId;
|
||||
}
|
||||
public TokenExchangeState withMsAppId(String msAppId) {
|
||||
this.msAppId = msAppId;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,73 +1,73 @@
|
|||
package com.microsoft.bot.schema;
|
||||
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
/**
|
||||
* An activity by which a bot can log internal information into a logged conversation transcript
|
||||
*/
|
||||
public class TraceActivity extends ActivityImpl {
|
||||
/**
|
||||
* Name of the trace activity
|
||||
*/
|
||||
private String _name;
|
||||
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Descriptive label for the trace
|
||||
*/
|
||||
private String _label;
|
||||
|
||||
public String getLabel() {
|
||||
return _label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this._label = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique string which identifies the format of the value object
|
||||
*/
|
||||
private String _value_type;
|
||||
|
||||
public String getValueType() {
|
||||
return _value_type;
|
||||
}
|
||||
|
||||
public void setValueType(String value_type) {
|
||||
_value_type = value_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open-ended value
|
||||
*/
|
||||
private Object _value;
|
||||
|
||||
Object getValue() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
void setValue(Object value) {
|
||||
_value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference to another conversation or activity
|
||||
*/
|
||||
private ConversationReference _relates_to;
|
||||
|
||||
ConversationReference getRelatesTo() {
|
||||
return _relates_to;
|
||||
}
|
||||
|
||||
void setRelatesTo(ConversationReference relates_to) {
|
||||
_relates_to = relates_to;
|
||||
}
|
||||
}
|
||||
package com.microsoft.bot.schema;
|
||||
|
||||
import com.microsoft.bot.schema.models.ConversationReference;
|
||||
|
||||
/**
|
||||
* An activity by which a bot can log internal information into a logged conversation transcript
|
||||
*/
|
||||
public class TraceActivity extends ActivityImpl {
|
||||
/**
|
||||
* Name of the trace activity
|
||||
*/
|
||||
private String _name;
|
||||
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Descriptive label for the trace
|
||||
*/
|
||||
private String _label;
|
||||
|
||||
public String getLabel() {
|
||||
return _label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this._label = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique string which identifies the format of the value object
|
||||
*/
|
||||
private String _value_type;
|
||||
|
||||
public String getValueType() {
|
||||
return _value_type;
|
||||
}
|
||||
|
||||
public void setValueType(String value_type) {
|
||||
_value_type = value_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open-ended value
|
||||
*/
|
||||
private Object _value;
|
||||
|
||||
Object getValue() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
void setValue(Object value) {
|
||||
_value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference to another conversation or activity
|
||||
*/
|
||||
private ConversationReference _relates_to;
|
||||
|
||||
ConversationReference getRelatesTo() {
|
||||
return _relates_to;
|
||||
}
|
||||
|
||||
void setRelatesTo(ConversationReference relates_to) {
|
||||
_relates_to = relates_to;
|
||||
}
|
||||
}
|
|
@ -1,82 +1,82 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines action types for clickable buttons.
|
||||
*/
|
||||
public enum ActionTypes {
|
||||
/** Enum value openUrl. */
|
||||
OPEN_URL("openUrl"),
|
||||
|
||||
/** Enum value imBack. */
|
||||
IM_BACK("imBack"),
|
||||
|
||||
/** Enum value postBack. */
|
||||
POST_BACK("postBack"),
|
||||
|
||||
/** Enum value playAudio. */
|
||||
PLAY_AUDIO("playAudio"),
|
||||
|
||||
/** Enum value playVideo. */
|
||||
PLAY_VIDEO("playVideo"),
|
||||
|
||||
/** Enum value showImage. */
|
||||
SHOW_IMAGE("showImage"),
|
||||
|
||||
/** Enum value downloadFile. */
|
||||
DOWNLOAD_FILE("downloadFile"),
|
||||
|
||||
/** Enum value signin. */
|
||||
SIGNIN("signin"),
|
||||
|
||||
/** Enum value call. */
|
||||
CALL("call"),
|
||||
|
||||
/** Enum value payment. */
|
||||
PAYMENT("payment"),
|
||||
|
||||
/** Enum value messageBack. */
|
||||
MESSAGE_BACK("messageBack");
|
||||
|
||||
/** The actual serialized value for a ActionTypes instance. */
|
||||
private String value;
|
||||
|
||||
ActionTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ActionTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ActionTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ActionTypes fromString(String value) {
|
||||
ActionTypes[] items = ActionTypes.values();
|
||||
for (ActionTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines action types for clickable buttons.
|
||||
*/
|
||||
public enum ActionTypes {
|
||||
/** Enum value openUrl. */
|
||||
OPEN_URL("openUrl"),
|
||||
|
||||
/** Enum value imBack. */
|
||||
IM_BACK("imBack"),
|
||||
|
||||
/** Enum value postBack. */
|
||||
POST_BACK("postBack"),
|
||||
|
||||
/** Enum value playAudio. */
|
||||
PLAY_AUDIO("playAudio"),
|
||||
|
||||
/** Enum value playVideo. */
|
||||
PLAY_VIDEO("playVideo"),
|
||||
|
||||
/** Enum value showImage. */
|
||||
SHOW_IMAGE("showImage"),
|
||||
|
||||
/** Enum value downloadFile. */
|
||||
DOWNLOAD_FILE("downloadFile"),
|
||||
|
||||
/** Enum value signin. */
|
||||
SIGNIN("signin"),
|
||||
|
||||
/** Enum value call. */
|
||||
CALL("call"),
|
||||
|
||||
/** Enum value payment. */
|
||||
PAYMENT("payment"),
|
||||
|
||||
/** Enum value messageBack. */
|
||||
MESSAGE_BACK("messageBack");
|
||||
|
||||
/** The actual serialized value for a ActionTypes instance. */
|
||||
private String value;
|
||||
|
||||
ActionTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ActionTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ActionTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ActionTypes fromString(String value) {
|
||||
ActionTypes[] items = ActionTypes.values();
|
||||
for (ActionTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,58 +1,58 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for ActivityImportance.
|
||||
*/
|
||||
public enum ActivityImportance {
|
||||
/** Enum value low. */
|
||||
LOW("low"),
|
||||
|
||||
/** Enum value normal. */
|
||||
NORMAL("normal"),
|
||||
|
||||
/** Enum value high. */
|
||||
HIGH("high");
|
||||
|
||||
/** The actual serialized value for a ActivityImportance instance. */
|
||||
private String value;
|
||||
|
||||
ActivityImportance(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ActivityImportance instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ActivityImportance object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ActivityImportance fromString(String value) {
|
||||
ActivityImportance[] items = ActivityImportance.values();
|
||||
for (ActivityImportance item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for ActivityImportance.
|
||||
*/
|
||||
public enum ActivityImportance {
|
||||
/** Enum value low. */
|
||||
LOW("low"),
|
||||
|
||||
/** Enum value normal. */
|
||||
NORMAL("normal"),
|
||||
|
||||
/** Enum value high. */
|
||||
HIGH("high");
|
||||
|
||||
/** The actual serialized value for a ActivityImportance instance. */
|
||||
private String value;
|
||||
|
||||
ActivityImportance(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ActivityImportance instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ActivityImportance object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ActivityImportance fromString(String value) {
|
||||
ActivityImportance[] items = ActivityImportance.values();
|
||||
for (ActivityImportance item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
|
@ -1,94 +1,94 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for ActivityTypes.
|
||||
*/
|
||||
public enum ActivityTypes {
|
||||
/** Enum value message. */
|
||||
MESSAGE("message"),
|
||||
|
||||
/** Enum value contactRelationUpdate. */
|
||||
CONTACT_RELATION_UPDATE("contactRelationUpdate"),
|
||||
|
||||
/** Enum value conversationUpdate. */
|
||||
CONVERSATION_UPDATE("conversationUpdate"),
|
||||
|
||||
/** Enum value typing. */
|
||||
TYPING("typing"),
|
||||
|
||||
/** Enum value endOfConversation. */
|
||||
END_OF_CONVERSATION("endOfConversation"),
|
||||
|
||||
/** Enum value event. */
|
||||
EVENT("event"),
|
||||
|
||||
/** Enum value invoke. */
|
||||
INVOKE("invoke"),
|
||||
|
||||
/** Enum value deleteUserData. */
|
||||
DELETE_USER_DATA("deleteUserData"),
|
||||
|
||||
/** Enum value messageUpdate. */
|
||||
MESSAGE_UPDATE("messageUpdate"),
|
||||
|
||||
/** Enum value messageDelete. */
|
||||
MESSAGE_DELETE("messageDelete"),
|
||||
|
||||
/** Enum value installationUpdate. */
|
||||
INSTALLATION_UPDATE("installationUpdate"),
|
||||
|
||||
/** Enum value messageReaction. */
|
||||
MESSAGE_REACTION("messageReaction"),
|
||||
|
||||
/** Enum value suggestion. */
|
||||
SUGGESTION("suggestion"),
|
||||
|
||||
/** Enum value trace. */
|
||||
TRACE("trace"),
|
||||
|
||||
/** Enum value handoff. */
|
||||
HANDOFF("handoff");
|
||||
|
||||
/** The actual serialized value for a ActivityTypes instance. */
|
||||
private String value;
|
||||
|
||||
ActivityTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ActivityTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ActivityTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ActivityTypes fromString(String value) {
|
||||
ActivityTypes[] items = ActivityTypes.values();
|
||||
for (ActivityTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for ActivityTypes.
|
||||
*/
|
||||
public enum ActivityTypes {
|
||||
/** Enum value message. */
|
||||
MESSAGE("message"),
|
||||
|
||||
/** Enum value contactRelationUpdate. */
|
||||
CONTACT_RELATION_UPDATE("contactRelationUpdate"),
|
||||
|
||||
/** Enum value conversationUpdate. */
|
||||
CONVERSATION_UPDATE("conversationUpdate"),
|
||||
|
||||
/** Enum value typing. */
|
||||
TYPING("typing"),
|
||||
|
||||
/** Enum value endOfConversation. */
|
||||
END_OF_CONVERSATION("endOfConversation"),
|
||||
|
||||
/** Enum value event. */
|
||||
EVENT("event"),
|
||||
|
||||
/** Enum value invoke. */
|
||||
INVOKE("invoke"),
|
||||
|
||||
/** Enum value deleteUserData. */
|
||||
DELETE_USER_DATA("deleteUserData"),
|
||||
|
||||
/** Enum value messageUpdate. */
|
||||
MESSAGE_UPDATE("messageUpdate"),
|
||||
|
||||
/** Enum value messageDelete. */
|
||||
MESSAGE_DELETE("messageDelete"),
|
||||
|
||||
/** Enum value installationUpdate. */
|
||||
INSTALLATION_UPDATE("installationUpdate"),
|
||||
|
||||
/** Enum value messageReaction. */
|
||||
MESSAGE_REACTION("messageReaction"),
|
||||
|
||||
/** Enum value suggestion. */
|
||||
SUGGESTION("suggestion"),
|
||||
|
||||
/** Enum value trace. */
|
||||
TRACE("trace"),
|
||||
|
||||
/** Enum value handoff. */
|
||||
HANDOFF("handoff");
|
||||
|
||||
/** The actual serialized value for a ActivityTypes instance. */
|
||||
private String value;
|
||||
|
||||
ActivityTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ActivityTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ActivityTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ActivityTypes fromString(String value) {
|
||||
ActivityTypes[] items = ActivityTypes.values();
|
||||
for (ActivityTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
|
@ -1,332 +1,332 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* An animation card (Ex: gif or short video clip).
|
||||
*/
|
||||
public class AnimationCard {
|
||||
/**
|
||||
* Title of this card.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Subtitle of this card.
|
||||
*/
|
||||
@JsonProperty(value = "subtitle")
|
||||
private String subtitle;
|
||||
|
||||
/**
|
||||
* Text of this card.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Thumbnail placeholder.
|
||||
*/
|
||||
@JsonProperty(value = "image")
|
||||
private ThumbnailUrl image;
|
||||
|
||||
/**
|
||||
* Media URLs for this card. When this field contains more than one URL, each URL is an alternative format of the same content.
|
||||
*/
|
||||
@JsonProperty(value = "media")
|
||||
private List<MediaUrl> media;
|
||||
|
||||
/**
|
||||
* Actions on this card.
|
||||
*/
|
||||
@JsonProperty(value = "buttons")
|
||||
private List<CardAction> buttons;
|
||||
|
||||
/**
|
||||
* This content may be shared with others (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "shareable")
|
||||
private Boolean shareable;
|
||||
|
||||
/**
|
||||
* Should the client loop playback at end of content (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autoloop")
|
||||
private Boolean autoloop;
|
||||
|
||||
/**
|
||||
* Should the client automatically start playback of media in this card
|
||||
* (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autostart")
|
||||
private Boolean autostart;
|
||||
|
||||
/**
|
||||
* Aspect ratio of thumbnail/media placeholder, allowed values are "16:9"
|
||||
* and "4:3".
|
||||
*/
|
||||
@JsonProperty(value = "aspect")
|
||||
private String aspect;
|
||||
|
||||
/**
|
||||
* Describes the length of the media content without requiring a receiver to open the content. Formatted as an ISO 8601 Duration field.
|
||||
*/
|
||||
@JsonProperty(value = "duration")
|
||||
private String duration;
|
||||
|
||||
/**
|
||||
* Supplementary parameter for this card.
|
||||
*/
|
||||
@JsonProperty(value = "value")
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subtitle value.
|
||||
*
|
||||
* @return the subtitle value
|
||||
*/
|
||||
public String subtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtitle value.
|
||||
*
|
||||
* @param subtitle the subtitle value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image value.
|
||||
*
|
||||
* @return the image value
|
||||
*/
|
||||
public ThumbnailUrl image() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image value.
|
||||
*
|
||||
* @param image the image value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withImage(ThumbnailUrl image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the media value.
|
||||
*
|
||||
* @return the media value
|
||||
*/
|
||||
public List<MediaUrl> media() {
|
||||
return this.media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the media value.
|
||||
*
|
||||
* @param media the media value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withMedia(List<MediaUrl> media) {
|
||||
this.media = media;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons value.
|
||||
*
|
||||
* @return the buttons value
|
||||
*/
|
||||
public List<CardAction> buttons() {
|
||||
return this.buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buttons value.
|
||||
*
|
||||
* @param buttons the buttons value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withButtons(List<CardAction> buttons) {
|
||||
this.buttons = buttons;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shareable value.
|
||||
*
|
||||
* @return the shareable value
|
||||
*/
|
||||
public Boolean shareable() {
|
||||
return this.shareable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shareable value.
|
||||
*
|
||||
* @param shareable the shareable value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withShareable(Boolean shareable) {
|
||||
this.shareable = shareable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autoloop value.
|
||||
*
|
||||
* @return the autoloop value
|
||||
*/
|
||||
public Boolean autoloop() {
|
||||
return this.autoloop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autoloop value.
|
||||
*
|
||||
* @param autoloop the autoloop value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withAutoloop(Boolean autoloop) {
|
||||
this.autoloop = autoloop;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autostart value.
|
||||
*
|
||||
* @return the autostart value
|
||||
*/
|
||||
public Boolean autostart() {
|
||||
return this.autostart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autostart value.
|
||||
*
|
||||
* @param autostart the autostart value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withAutostart(Boolean autostart) {
|
||||
this.autostart = autostart;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the aspect value.
|
||||
*
|
||||
* @return the aspect value
|
||||
*/
|
||||
public String aspect() {
|
||||
return this.aspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the aspect value.
|
||||
*
|
||||
* @param aspect the aspect value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withAspect(String aspect) {
|
||||
this.aspect = aspect;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration value.
|
||||
*/
|
||||
public String duration(){
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration value.
|
||||
*
|
||||
* @param duration the duration value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withDuration(String duration){
|
||||
this.duration = duration;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value value.
|
||||
*
|
||||
* @return the value value
|
||||
*/
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value value.
|
||||
*
|
||||
* @param value the value value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withValue(Object value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* An animation card (Ex: gif or short video clip).
|
||||
*/
|
||||
public class AnimationCard {
|
||||
/**
|
||||
* Title of this card.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Subtitle of this card.
|
||||
*/
|
||||
@JsonProperty(value = "subtitle")
|
||||
private String subtitle;
|
||||
|
||||
/**
|
||||
* Text of this card.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Thumbnail placeholder.
|
||||
*/
|
||||
@JsonProperty(value = "image")
|
||||
private ThumbnailUrl image;
|
||||
|
||||
/**
|
||||
* Media URLs for this card. When this field contains more than one URL, each URL is an alternative format of the same content.
|
||||
*/
|
||||
@JsonProperty(value = "media")
|
||||
private List<MediaUrl> media;
|
||||
|
||||
/**
|
||||
* Actions on this card.
|
||||
*/
|
||||
@JsonProperty(value = "buttons")
|
||||
private List<CardAction> buttons;
|
||||
|
||||
/**
|
||||
* This content may be shared with others (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "shareable")
|
||||
private Boolean shareable;
|
||||
|
||||
/**
|
||||
* Should the client loop playback at end of content (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autoloop")
|
||||
private Boolean autoloop;
|
||||
|
||||
/**
|
||||
* Should the client automatically start playback of media in this card
|
||||
* (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autostart")
|
||||
private Boolean autostart;
|
||||
|
||||
/**
|
||||
* Aspect ratio of thumbnail/media placeholder, allowed values are "16:9"
|
||||
* and "4:3".
|
||||
*/
|
||||
@JsonProperty(value = "aspect")
|
||||
private String aspect;
|
||||
|
||||
/**
|
||||
* Describes the length of the media content without requiring a receiver to open the content. Formatted as an ISO 8601 Duration field.
|
||||
*/
|
||||
@JsonProperty(value = "duration")
|
||||
private String duration;
|
||||
|
||||
/**
|
||||
* Supplementary parameter for this card.
|
||||
*/
|
||||
@JsonProperty(value = "value")
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subtitle value.
|
||||
*
|
||||
* @return the subtitle value
|
||||
*/
|
||||
public String subtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtitle value.
|
||||
*
|
||||
* @param subtitle the subtitle value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image value.
|
||||
*
|
||||
* @return the image value
|
||||
*/
|
||||
public ThumbnailUrl image() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image value.
|
||||
*
|
||||
* @param image the image value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withImage(ThumbnailUrl image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the media value.
|
||||
*
|
||||
* @return the media value
|
||||
*/
|
||||
public List<MediaUrl> media() {
|
||||
return this.media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the media value.
|
||||
*
|
||||
* @param media the media value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withMedia(List<MediaUrl> media) {
|
||||
this.media = media;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons value.
|
||||
*
|
||||
* @return the buttons value
|
||||
*/
|
||||
public List<CardAction> buttons() {
|
||||
return this.buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buttons value.
|
||||
*
|
||||
* @param buttons the buttons value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withButtons(List<CardAction> buttons) {
|
||||
this.buttons = buttons;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shareable value.
|
||||
*
|
||||
* @return the shareable value
|
||||
*/
|
||||
public Boolean shareable() {
|
||||
return this.shareable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shareable value.
|
||||
*
|
||||
* @param shareable the shareable value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withShareable(Boolean shareable) {
|
||||
this.shareable = shareable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autoloop value.
|
||||
*
|
||||
* @return the autoloop value
|
||||
*/
|
||||
public Boolean autoloop() {
|
||||
return this.autoloop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autoloop value.
|
||||
*
|
||||
* @param autoloop the autoloop value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withAutoloop(Boolean autoloop) {
|
||||
this.autoloop = autoloop;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autostart value.
|
||||
*
|
||||
* @return the autostart value
|
||||
*/
|
||||
public Boolean autostart() {
|
||||
return this.autostart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autostart value.
|
||||
*
|
||||
* @param autostart the autostart value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withAutostart(Boolean autostart) {
|
||||
this.autostart = autostart;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the aspect value.
|
||||
*
|
||||
* @return the aspect value
|
||||
*/
|
||||
public String aspect() {
|
||||
return this.aspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the aspect value.
|
||||
*
|
||||
* @param aspect the aspect value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withAspect(String aspect) {
|
||||
this.aspect = aspect;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration value.
|
||||
*/
|
||||
public String duration(){
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration value.
|
||||
*
|
||||
* @param duration the duration value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withDuration(String duration){
|
||||
this.duration = duration;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value value.
|
||||
*
|
||||
* @return the value value
|
||||
*/
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value value.
|
||||
*
|
||||
* @param value the value value to set
|
||||
* @return the AnimationCard object itself.
|
||||
*/
|
||||
public AnimationCard withValue(Object value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,185 +1,185 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An attachment within an activity.
|
||||
*/
|
||||
public class Attachment {
|
||||
/**
|
||||
* mimetype/Contenttype for the file.
|
||||
*/
|
||||
@JsonProperty(value = "contentType")
|
||||
private String contentType;
|
||||
|
||||
/**
|
||||
* Content Url.
|
||||
*/
|
||||
@JsonProperty(value = "contentUrl")
|
||||
private String contentUrl;
|
||||
|
||||
/**
|
||||
* Embedded content.
|
||||
*/
|
||||
@JsonProperty(value = "content")
|
||||
private Object content;
|
||||
|
||||
/**
|
||||
* (OPTIONAL) The name of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* (OPTIONAL) Thumbnail associated with attachment.
|
||||
*/
|
||||
@JsonProperty(value = "thumbnailUrl")
|
||||
private String thumbnailUrl;
|
||||
|
||||
/**
|
||||
* Get the contentType value.
|
||||
*
|
||||
* @return the contentType value
|
||||
*/
|
||||
public String contentType() {
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contentType value.
|
||||
*
|
||||
* @param contentType the contentType value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contentUrl value.
|
||||
*
|
||||
* @return the contentUrl value
|
||||
*/
|
||||
public String contentUrl() {
|
||||
return this.contentUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contentUrl value.
|
||||
*
|
||||
* @param contentUrl the contentUrl value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withContentUrl(String contentUrl) {
|
||||
this.contentUrl = contentUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content value.
|
||||
*
|
||||
* @return the content value
|
||||
*/
|
||||
public Object content() {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content value.
|
||||
*
|
||||
* @param content the content value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withContent(Object content) {
|
||||
this.content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thumbnailUrl value.
|
||||
*
|
||||
* @return the thumbnailUrl value
|
||||
*/
|
||||
public String thumbnailUrl() {
|
||||
return this.thumbnailUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnailUrl value.
|
||||
*
|
||||
* @param thumbnailUrl the thumbnailUrl value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withThumbnailUrl(String thumbnailUrl) {
|
||||
this.thumbnailUrl = thumbnailUrl;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Holds the overflow properties that aren't first class
|
||||
* properties in the object. This allows extensibility
|
||||
* while maintaining the object.
|
||||
*
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
/**
|
||||
* Overflow properties.
|
||||
* Properties that are not modelled as first class properties in the object are accessible here.
|
||||
* Note: A property value can be be nested.
|
||||
*
|
||||
* @return A Key-Value map of the properties
|
||||
*/
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> properties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set overflow properties.
|
||||
*
|
||||
* @param key Key for the property
|
||||
* @param value JsonNode of value (can be nested)
|
||||
*
|
||||
*/
|
||||
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An attachment within an activity.
|
||||
*/
|
||||
public class Attachment {
|
||||
/**
|
||||
* mimetype/Contenttype for the file.
|
||||
*/
|
||||
@JsonProperty(value = "contentType")
|
||||
private String contentType;
|
||||
|
||||
/**
|
||||
* Content Url.
|
||||
*/
|
||||
@JsonProperty(value = "contentUrl")
|
||||
private String contentUrl;
|
||||
|
||||
/**
|
||||
* Embedded content.
|
||||
*/
|
||||
@JsonProperty(value = "content")
|
||||
private Object content;
|
||||
|
||||
/**
|
||||
* (OPTIONAL) The name of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* (OPTIONAL) Thumbnail associated with attachment.
|
||||
*/
|
||||
@JsonProperty(value = "thumbnailUrl")
|
||||
private String thumbnailUrl;
|
||||
|
||||
/**
|
||||
* Get the contentType value.
|
||||
*
|
||||
* @return the contentType value
|
||||
*/
|
||||
public String contentType() {
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contentType value.
|
||||
*
|
||||
* @param contentType the contentType value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contentUrl value.
|
||||
*
|
||||
* @return the contentUrl value
|
||||
*/
|
||||
public String contentUrl() {
|
||||
return this.contentUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contentUrl value.
|
||||
*
|
||||
* @param contentUrl the contentUrl value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withContentUrl(String contentUrl) {
|
||||
this.contentUrl = contentUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content value.
|
||||
*
|
||||
* @return the content value
|
||||
*/
|
||||
public Object content() {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content value.
|
||||
*
|
||||
* @param content the content value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withContent(Object content) {
|
||||
this.content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thumbnailUrl value.
|
||||
*
|
||||
* @return the thumbnailUrl value
|
||||
*/
|
||||
public String thumbnailUrl() {
|
||||
return this.thumbnailUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnailUrl value.
|
||||
*
|
||||
* @param thumbnailUrl the thumbnailUrl value to set
|
||||
* @return the Attachment object itself.
|
||||
*/
|
||||
public Attachment withThumbnailUrl(String thumbnailUrl) {
|
||||
this.thumbnailUrl = thumbnailUrl;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Holds the overflow properties that aren't first class
|
||||
* properties in the object. This allows extensibility
|
||||
* while maintaining the object.
|
||||
*
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
/**
|
||||
* Overflow properties.
|
||||
* Properties that are not modelled as first class properties in the object are accessible here.
|
||||
* Note: A property value can be be nested.
|
||||
*
|
||||
* @return A Key-Value map of the properties
|
||||
*/
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> properties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set overflow properties.
|
||||
*
|
||||
* @param key Key for the property
|
||||
* @param value JsonNode of value (can be nested)
|
||||
*
|
||||
*/
|
||||
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,123 +1,123 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Attachment data.
|
||||
*/
|
||||
public class AttachmentData {
|
||||
/**
|
||||
* Content-Type of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "type")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* Name of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Attachment content.
|
||||
*/
|
||||
@JsonProperty(value = "originalBase64")
|
||||
private byte[] originalBase64;
|
||||
|
||||
/**
|
||||
* Attachment thumbnail.
|
||||
*/
|
||||
@JsonProperty(value = "thumbnailBase64")
|
||||
private byte[] thumbnailBase64;
|
||||
|
||||
/**
|
||||
* Get the type value.
|
||||
*
|
||||
* @return the type value
|
||||
*/
|
||||
public String type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type value.
|
||||
*
|
||||
* @param type the type value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withType(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the originalBase64 value.
|
||||
*
|
||||
* @return the originalBase64 value
|
||||
*/
|
||||
public byte[] originalBase64() {
|
||||
return this.originalBase64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the originalBase64 value.
|
||||
*
|
||||
* @param originalBase64 the originalBase64 value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withOriginalBase64(byte[] originalBase64) {
|
||||
this.originalBase64 = originalBase64;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thumbnailBase64 value.
|
||||
*
|
||||
* @return the thumbnailBase64 value
|
||||
*/
|
||||
public byte[] thumbnailBase64() {
|
||||
return this.thumbnailBase64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnailBase64 value.
|
||||
*
|
||||
* @param thumbnailBase64 the thumbnailBase64 value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withThumbnailBase64(byte[] thumbnailBase64) {
|
||||
this.thumbnailBase64 = thumbnailBase64;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Attachment data.
|
||||
*/
|
||||
public class AttachmentData {
|
||||
/**
|
||||
* Content-Type of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "type")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* Name of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Attachment content.
|
||||
*/
|
||||
@JsonProperty(value = "originalBase64")
|
||||
private byte[] originalBase64;
|
||||
|
||||
/**
|
||||
* Attachment thumbnail.
|
||||
*/
|
||||
@JsonProperty(value = "thumbnailBase64")
|
||||
private byte[] thumbnailBase64;
|
||||
|
||||
/**
|
||||
* Get the type value.
|
||||
*
|
||||
* @return the type value
|
||||
*/
|
||||
public String type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type value.
|
||||
*
|
||||
* @param type the type value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withType(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the originalBase64 value.
|
||||
*
|
||||
* @return the originalBase64 value
|
||||
*/
|
||||
public byte[] originalBase64() {
|
||||
return this.originalBase64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the originalBase64 value.
|
||||
*
|
||||
* @param originalBase64 the originalBase64 value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withOriginalBase64(byte[] originalBase64) {
|
||||
this.originalBase64 = originalBase64;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thumbnailBase64 value.
|
||||
*
|
||||
* @return the thumbnailBase64 value
|
||||
*/
|
||||
public byte[] thumbnailBase64() {
|
||||
return this.thumbnailBase64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnailBase64 value.
|
||||
*
|
||||
* @param thumbnailBase64 the thumbnailBase64 value to set
|
||||
* @return the AttachmentData object itself.
|
||||
*/
|
||||
public AttachmentData withThumbnailBase64(byte[] thumbnailBase64) {
|
||||
this.thumbnailBase64 = thumbnailBase64;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +1,98 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Metdata for an attachment.
|
||||
*/
|
||||
public class AttachmentInfo {
|
||||
/**
|
||||
* Name of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* ContentType of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "type")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* attachment views.
|
||||
*/
|
||||
@JsonProperty(value = "views")
|
||||
private List<AttachmentView> views;
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the AttachmentInfo object itself.
|
||||
*/
|
||||
public AttachmentInfo withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type value.
|
||||
*
|
||||
* @return the type value
|
||||
*/
|
||||
public String type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type value.
|
||||
*
|
||||
* @param type the type value to set
|
||||
* @return the AttachmentInfo object itself.
|
||||
*/
|
||||
public AttachmentInfo withType(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the views value.
|
||||
*
|
||||
* @return the views value
|
||||
*/
|
||||
public List<AttachmentView> views() {
|
||||
return this.views;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the views value.
|
||||
*
|
||||
* @param views the views value to set
|
||||
* @return the AttachmentInfo object itself.
|
||||
*/
|
||||
public AttachmentInfo withViews(List<AttachmentView> views) {
|
||||
this.views = views;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Metdata for an attachment.
|
||||
*/
|
||||
public class AttachmentInfo {
|
||||
/**
|
||||
* Name of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* ContentType of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "type")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* attachment views.
|
||||
*/
|
||||
@JsonProperty(value = "views")
|
||||
private List<AttachmentView> views;
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the AttachmentInfo object itself.
|
||||
*/
|
||||
public AttachmentInfo withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type value.
|
||||
*
|
||||
* @return the type value
|
||||
*/
|
||||
public String type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type value.
|
||||
*
|
||||
* @param type the type value to set
|
||||
* @return the AttachmentInfo object itself.
|
||||
*/
|
||||
public AttachmentInfo withType(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the views value.
|
||||
*
|
||||
* @return the views value
|
||||
*/
|
||||
public List<AttachmentView> views() {
|
||||
return this.views;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the views value.
|
||||
*
|
||||
* @param views the views value to set
|
||||
* @return the AttachmentInfo object itself.
|
||||
*/
|
||||
public AttachmentInfo withViews(List<AttachmentView> views) {
|
||||
this.views = views;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,55 +1,55 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for AttachmentLayoutTypes.
|
||||
*/
|
||||
public enum AttachmentLayoutTypes {
|
||||
/** Enum value list. */
|
||||
LIST("list"),
|
||||
|
||||
/** Enum value carousel. */
|
||||
CAROUSEL("carousel");
|
||||
|
||||
/** The actual serialized value for a AttachmentLayoutTypes instance. */
|
||||
private String value;
|
||||
|
||||
AttachmentLayoutTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a AttachmentLayoutTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed AttachmentLayoutTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static AttachmentLayoutTypes fromString(String value) {
|
||||
AttachmentLayoutTypes[] items = AttachmentLayoutTypes.values();
|
||||
for (AttachmentLayoutTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for AttachmentLayoutTypes.
|
||||
*/
|
||||
public enum AttachmentLayoutTypes {
|
||||
/** Enum value list. */
|
||||
LIST("list"),
|
||||
|
||||
/** Enum value carousel. */
|
||||
CAROUSEL("carousel");
|
||||
|
||||
/** The actual serialized value for a AttachmentLayoutTypes instance. */
|
||||
private String value;
|
||||
|
||||
AttachmentLayoutTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a AttachmentLayoutTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed AttachmentLayoutTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static AttachmentLayoutTypes fromString(String value) {
|
||||
AttachmentLayoutTypes[] items = AttachmentLayoutTypes.values();
|
||||
for (AttachmentLayoutTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
|
@ -1,71 +1,71 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Attachment View name and size.
|
||||
*/
|
||||
public class AttachmentView {
|
||||
/**
|
||||
* Id of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "viewId")
|
||||
private String viewId;
|
||||
|
||||
/**
|
||||
* Size of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "size")
|
||||
private Integer size;
|
||||
|
||||
/**
|
||||
* Get the viewId value.
|
||||
*
|
||||
* @return the viewId value
|
||||
*/
|
||||
public String viewId() {
|
||||
return this.viewId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the viewId value.
|
||||
*
|
||||
* @param viewId the viewId value to set
|
||||
* @return the AttachmentView object itself.
|
||||
*/
|
||||
public AttachmentView withViewId(String viewId) {
|
||||
this.viewId = viewId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size value.
|
||||
*
|
||||
* @return the size value
|
||||
*/
|
||||
public Integer size() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size value.
|
||||
*
|
||||
* @param size the size value to set
|
||||
* @return the AttachmentView object itself.
|
||||
*/
|
||||
public AttachmentView withSize(Integer size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Attachment View name and size.
|
||||
*/
|
||||
public class AttachmentView {
|
||||
/**
|
||||
* Id of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "viewId")
|
||||
private String viewId;
|
||||
|
||||
/**
|
||||
* Size of the attachment.
|
||||
*/
|
||||
@JsonProperty(value = "size")
|
||||
private Integer size;
|
||||
|
||||
/**
|
||||
* Get the viewId value.
|
||||
*
|
||||
* @return the viewId value
|
||||
*/
|
||||
public String viewId() {
|
||||
return this.viewId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the viewId value.
|
||||
*
|
||||
* @param viewId the viewId value to set
|
||||
* @return the AttachmentView object itself.
|
||||
*/
|
||||
public AttachmentView withViewId(String viewId) {
|
||||
this.viewId = viewId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size value.
|
||||
*
|
||||
* @return the size value
|
||||
*/
|
||||
public Integer size() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size value.
|
||||
*
|
||||
* @param size the size value to set
|
||||
* @return the AttachmentView object itself.
|
||||
*/
|
||||
public AttachmentView withSize(Integer size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,332 +1,332 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Audio card.
|
||||
*/
|
||||
public class AudioCard {
|
||||
/**
|
||||
* Title of this card.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Subtitle of this card.
|
||||
*/
|
||||
@JsonProperty(value = "subtitle")
|
||||
private String subtitle;
|
||||
|
||||
/**
|
||||
* Text of this card.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Thumbnail placeholder.
|
||||
*/
|
||||
@JsonProperty(value = "image")
|
||||
private ThumbnailUrl image;
|
||||
|
||||
/**
|
||||
* Media URLs for this card. When this field contains more than one URL, each URL is an alternative format of the same content.
|
||||
*/
|
||||
@JsonProperty(value = "media")
|
||||
private List<MediaUrl> media;
|
||||
|
||||
/**
|
||||
* Actions on this card.
|
||||
*/
|
||||
@JsonProperty(value = "buttons")
|
||||
private List<CardAction> buttons;
|
||||
|
||||
/**
|
||||
* This content may be shared with others (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "shareable")
|
||||
private Boolean shareable;
|
||||
|
||||
/**
|
||||
* Should the client loop playback at end of content (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autoloop")
|
||||
private Boolean autoloop;
|
||||
|
||||
/**
|
||||
* Should the client automatically start playback of media in this card
|
||||
* (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autostart")
|
||||
private Boolean autostart;
|
||||
|
||||
/**
|
||||
* Aspect ratio of thumbnail/media placeholder, allowed values are "16:9"
|
||||
* and "4:3".
|
||||
*/
|
||||
@JsonProperty(value = "aspect")
|
||||
private String aspect;
|
||||
|
||||
/**
|
||||
* Describes the length of the media content without requiring a receiver to open the content. Formatted as an ISO 8601 Duration field.
|
||||
*/
|
||||
@JsonProperty(value = "duration")
|
||||
private String duration;
|
||||
|
||||
/**
|
||||
* Supplementary parameter for this card.
|
||||
*/
|
||||
@JsonProperty(value = "value")
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subtitle value.
|
||||
*
|
||||
* @return the subtitle value
|
||||
*/
|
||||
public String subtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtitle value.
|
||||
*
|
||||
* @param subtitle the subtitle value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image value.
|
||||
*
|
||||
* @return the image value
|
||||
*/
|
||||
public ThumbnailUrl image() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image value.
|
||||
*
|
||||
* @param image the image value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withImage(ThumbnailUrl image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the media value.
|
||||
*
|
||||
* @return the media value
|
||||
*/
|
||||
public List<MediaUrl> media() {
|
||||
return this.media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the media value.
|
||||
*
|
||||
* @param media the media value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withMedia(List<MediaUrl> media) {
|
||||
this.media = media;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons value.
|
||||
*
|
||||
* @return the buttons value
|
||||
*/
|
||||
public List<CardAction> buttons() {
|
||||
return this.buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buttons value.
|
||||
*
|
||||
* @param buttons the buttons value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withButtons(List<CardAction> buttons) {
|
||||
this.buttons = buttons;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shareable value.
|
||||
*
|
||||
* @return the shareable value
|
||||
*/
|
||||
public Boolean shareable() {
|
||||
return this.shareable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shareable value.
|
||||
*
|
||||
* @param shareable the shareable value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withShareable(Boolean shareable) {
|
||||
this.shareable = shareable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autoloop value.
|
||||
*
|
||||
* @return the autoloop value
|
||||
*/
|
||||
public Boolean autoloop() {
|
||||
return this.autoloop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autoloop value.
|
||||
*
|
||||
* @param autoloop the autoloop value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withAutoloop(Boolean autoloop) {
|
||||
this.autoloop = autoloop;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autostart value.
|
||||
*
|
||||
* @return the autostart value
|
||||
*/
|
||||
public Boolean autostart() {
|
||||
return this.autostart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autostart value.
|
||||
*
|
||||
* @param autostart the autostart value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withAutostart(Boolean autostart) {
|
||||
this.autostart = autostart;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the aspect value.
|
||||
*
|
||||
* @return the aspect value
|
||||
*/
|
||||
public String aspect() {
|
||||
return this.aspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the aspect value.
|
||||
*
|
||||
* @param aspect the aspect value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withAspect(String aspect) {
|
||||
this.aspect = aspect;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration value.
|
||||
*/
|
||||
public String duration(){
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration value.
|
||||
*
|
||||
* @param duration the duration value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withDuration(String duration){
|
||||
this.duration = duration;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value value.
|
||||
*
|
||||
* @return the value value
|
||||
*/
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value value.
|
||||
*
|
||||
* @param value the value value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withValue(Object value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Audio card.
|
||||
*/
|
||||
public class AudioCard {
|
||||
/**
|
||||
* Title of this card.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Subtitle of this card.
|
||||
*/
|
||||
@JsonProperty(value = "subtitle")
|
||||
private String subtitle;
|
||||
|
||||
/**
|
||||
* Text of this card.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Thumbnail placeholder.
|
||||
*/
|
||||
@JsonProperty(value = "image")
|
||||
private ThumbnailUrl image;
|
||||
|
||||
/**
|
||||
* Media URLs for this card. When this field contains more than one URL, each URL is an alternative format of the same content.
|
||||
*/
|
||||
@JsonProperty(value = "media")
|
||||
private List<MediaUrl> media;
|
||||
|
||||
/**
|
||||
* Actions on this card.
|
||||
*/
|
||||
@JsonProperty(value = "buttons")
|
||||
private List<CardAction> buttons;
|
||||
|
||||
/**
|
||||
* This content may be shared with others (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "shareable")
|
||||
private Boolean shareable;
|
||||
|
||||
/**
|
||||
* Should the client loop playback at end of content (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autoloop")
|
||||
private Boolean autoloop;
|
||||
|
||||
/**
|
||||
* Should the client automatically start playback of media in this card
|
||||
* (default:true).
|
||||
*/
|
||||
@JsonProperty(value = "autostart")
|
||||
private Boolean autostart;
|
||||
|
||||
/**
|
||||
* Aspect ratio of thumbnail/media placeholder, allowed values are "16:9"
|
||||
* and "4:3".
|
||||
*/
|
||||
@JsonProperty(value = "aspect")
|
||||
private String aspect;
|
||||
|
||||
/**
|
||||
* Describes the length of the media content without requiring a receiver to open the content. Formatted as an ISO 8601 Duration field.
|
||||
*/
|
||||
@JsonProperty(value = "duration")
|
||||
private String duration;
|
||||
|
||||
/**
|
||||
* Supplementary parameter for this card.
|
||||
*/
|
||||
@JsonProperty(value = "value")
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subtitle value.
|
||||
*
|
||||
* @return the subtitle value
|
||||
*/
|
||||
public String subtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtitle value.
|
||||
*
|
||||
* @param subtitle the subtitle value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image value.
|
||||
*
|
||||
* @return the image value
|
||||
*/
|
||||
public ThumbnailUrl image() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image value.
|
||||
*
|
||||
* @param image the image value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withImage(ThumbnailUrl image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the media value.
|
||||
*
|
||||
* @return the media value
|
||||
*/
|
||||
public List<MediaUrl> media() {
|
||||
return this.media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the media value.
|
||||
*
|
||||
* @param media the media value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withMedia(List<MediaUrl> media) {
|
||||
this.media = media;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons value.
|
||||
*
|
||||
* @return the buttons value
|
||||
*/
|
||||
public List<CardAction> buttons() {
|
||||
return this.buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buttons value.
|
||||
*
|
||||
* @param buttons the buttons value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withButtons(List<CardAction> buttons) {
|
||||
this.buttons = buttons;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shareable value.
|
||||
*
|
||||
* @return the shareable value
|
||||
*/
|
||||
public Boolean shareable() {
|
||||
return this.shareable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shareable value.
|
||||
*
|
||||
* @param shareable the shareable value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withShareable(Boolean shareable) {
|
||||
this.shareable = shareable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autoloop value.
|
||||
*
|
||||
* @return the autoloop value
|
||||
*/
|
||||
public Boolean autoloop() {
|
||||
return this.autoloop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autoloop value.
|
||||
*
|
||||
* @param autoloop the autoloop value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withAutoloop(Boolean autoloop) {
|
||||
this.autoloop = autoloop;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the autostart value.
|
||||
*
|
||||
* @return the autostart value
|
||||
*/
|
||||
public Boolean autostart() {
|
||||
return this.autostart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autostart value.
|
||||
*
|
||||
* @param autostart the autostart value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withAutostart(Boolean autostart) {
|
||||
this.autostart = autostart;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the aspect value.
|
||||
*
|
||||
* @return the aspect value
|
||||
*/
|
||||
public String aspect() {
|
||||
return this.aspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the aspect value.
|
||||
*
|
||||
* @param aspect the aspect value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withAspect(String aspect) {
|
||||
this.aspect = aspect;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration value.
|
||||
*/
|
||||
public String duration(){
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration value.
|
||||
*
|
||||
* @param duration the duration value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withDuration(String duration){
|
||||
this.duration = duration;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value value.
|
||||
*
|
||||
* @return the value value
|
||||
*/
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value value.
|
||||
*
|
||||
* @param value the value value to set
|
||||
* @return the AudioCard object itself.
|
||||
*/
|
||||
public AudioCard withValue(Object value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,176 +1,176 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* A basic card.
|
||||
*/
|
||||
public class BasicCard {
|
||||
/**
|
||||
* Title of the card.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Subtitle of the card.
|
||||
*/
|
||||
@JsonProperty(value = "subtitle")
|
||||
private String subtitle;
|
||||
|
||||
/**
|
||||
* Text for the card.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Array of images for the card.
|
||||
*/
|
||||
@JsonProperty(value = "images")
|
||||
private List<CardImage> images;
|
||||
|
||||
/**
|
||||
* Set of actions applicable to the current card.
|
||||
*/
|
||||
@JsonProperty(value = "buttons")
|
||||
private List<CardAction> buttons;
|
||||
|
||||
/**
|
||||
* This action will be activated when user taps on the card itself.
|
||||
*/
|
||||
@JsonProperty(value = "tap")
|
||||
private CardAction tap;
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subtitle value.
|
||||
*
|
||||
* @return the subtitle value
|
||||
*/
|
||||
public String subtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtitle value.
|
||||
*
|
||||
* @param subtitle the subtitle value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the images value.
|
||||
*
|
||||
* @return the images value
|
||||
*/
|
||||
public List<CardImage> images() {
|
||||
return this.images;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the images value.
|
||||
*
|
||||
* @param images the images value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withImages(List<CardImage> images) {
|
||||
this.images = images;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons value.
|
||||
*
|
||||
* @return the buttons value
|
||||
*/
|
||||
public List<CardAction> buttons() {
|
||||
return this.buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buttons value.
|
||||
*
|
||||
* @param buttons the buttons value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withButtons(List<CardAction> buttons) {
|
||||
this.buttons = buttons;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tap value.
|
||||
*
|
||||
* @return the tap value
|
||||
*/
|
||||
public CardAction tap() {
|
||||
return this.tap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tap value.
|
||||
*
|
||||
* @param tap the tap value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withTap(CardAction tap) {
|
||||
this.tap = tap;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* A basic card.
|
||||
*/
|
||||
public class BasicCard {
|
||||
/**
|
||||
* Title of the card.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Subtitle of the card.
|
||||
*/
|
||||
@JsonProperty(value = "subtitle")
|
||||
private String subtitle;
|
||||
|
||||
/**
|
||||
* Text for the card.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Array of images for the card.
|
||||
*/
|
||||
@JsonProperty(value = "images")
|
||||
private List<CardImage> images;
|
||||
|
||||
/**
|
||||
* Set of actions applicable to the current card.
|
||||
*/
|
||||
@JsonProperty(value = "buttons")
|
||||
private List<CardAction> buttons;
|
||||
|
||||
/**
|
||||
* This action will be activated when user taps on the card itself.
|
||||
*/
|
||||
@JsonProperty(value = "tap")
|
||||
private CardAction tap;
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subtitle value.
|
||||
*
|
||||
* @return the subtitle value
|
||||
*/
|
||||
public String subtitle() {
|
||||
return this.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtitle value.
|
||||
*
|
||||
* @param subtitle the subtitle value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the images value.
|
||||
*
|
||||
* @return the images value
|
||||
*/
|
||||
public List<CardImage> images() {
|
||||
return this.images;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the images value.
|
||||
*
|
||||
* @param images the images value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withImages(List<CardImage> images) {
|
||||
this.images = images;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons value.
|
||||
*
|
||||
* @return the buttons value
|
||||
*/
|
||||
public List<CardAction> buttons() {
|
||||
return this.buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buttons value.
|
||||
*
|
||||
* @param buttons the buttons value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withButtons(List<CardAction> buttons) {
|
||||
this.buttons = buttons;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tap value.
|
||||
*
|
||||
* @return the tap value
|
||||
*/
|
||||
public CardAction tap() {
|
||||
return this.tap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tap value.
|
||||
*
|
||||
* @param tap the tap value to set
|
||||
* @return the BasicCard object itself.
|
||||
*/
|
||||
public BasicCard withTap(CardAction tap) {
|
||||
this.tap = tap;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,201 +1,201 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* A clickable action.
|
||||
*/
|
||||
public class CardAction {
|
||||
/**
|
||||
* The type of action implemented by this button. Possible values include:
|
||||
* 'openUrl', 'imBack', 'postBack', 'playAudio', 'playVideo', 'showImage',
|
||||
* 'downloadFile', 'signin', 'call', 'payment', 'messageBack'.
|
||||
*/
|
||||
@JsonProperty(value = "type")
|
||||
private ActionTypes type;
|
||||
|
||||
/**
|
||||
* Text description which appears on the button.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Image URL which will appear on the button, next to text label.
|
||||
*/
|
||||
@JsonProperty(value = "image")
|
||||
private String image;
|
||||
|
||||
/**
|
||||
* Text for this action.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* (Optional) text to display in the chat feed if the button is clicked.
|
||||
*/
|
||||
@JsonProperty(value = "displayText")
|
||||
private String displayText;
|
||||
|
||||
/**
|
||||
* Supplementary parameter for action. Content of this property depends on
|
||||
* the ActionType.
|
||||
*/
|
||||
@JsonProperty(value = "value")
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Channel-specific data associated with this action.
|
||||
*/
|
||||
@JsonProperty(value = "channelData")
|
||||
private Object channelData;
|
||||
|
||||
/**
|
||||
* Get the type value.
|
||||
*
|
||||
* @return the type value
|
||||
*/
|
||||
public ActionTypes type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type value.
|
||||
*
|
||||
* @param type the type value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withType(ActionTypes type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image value.
|
||||
*
|
||||
* @return the image value
|
||||
*/
|
||||
public String image() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image value.
|
||||
*
|
||||
* @param image the image value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withImage(String image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayText value.
|
||||
*
|
||||
* @return the displayText value
|
||||
*/
|
||||
public String displayText() {
|
||||
return this.displayText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the displayText value.
|
||||
*
|
||||
* @param displayText the displayText value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withDisplayText(String displayText) {
|
||||
this.displayText = displayText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value value.
|
||||
*
|
||||
* @return the value value
|
||||
*/
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value value.
|
||||
*
|
||||
* @param value the value value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withValue(Object value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the channelData value.
|
||||
*/
|
||||
public Object channelData(){
|
||||
return this.channelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the channelData value.
|
||||
*
|
||||
* @param channelData The channelData object to set.
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withChannelData(Object channelData){
|
||||
this.channelData = channelData;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* A clickable action.
|
||||
*/
|
||||
public class CardAction {
|
||||
/**
|
||||
* The type of action implemented by this button. Possible values include:
|
||||
* 'openUrl', 'imBack', 'postBack', 'playAudio', 'playVideo', 'showImage',
|
||||
* 'downloadFile', 'signin', 'call', 'payment', 'messageBack'.
|
||||
*/
|
||||
@JsonProperty(value = "type")
|
||||
private ActionTypes type;
|
||||
|
||||
/**
|
||||
* Text description which appears on the button.
|
||||
*/
|
||||
@JsonProperty(value = "title")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Image URL which will appear on the button, next to text label.
|
||||
*/
|
||||
@JsonProperty(value = "image")
|
||||
private String image;
|
||||
|
||||
/**
|
||||
* Text for this action.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* (Optional) text to display in the chat feed if the button is clicked.
|
||||
*/
|
||||
@JsonProperty(value = "displayText")
|
||||
private String displayText;
|
||||
|
||||
/**
|
||||
* Supplementary parameter for action. Content of this property depends on
|
||||
* the ActionType.
|
||||
*/
|
||||
@JsonProperty(value = "value")
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Channel-specific data associated with this action.
|
||||
*/
|
||||
@JsonProperty(value = "channelData")
|
||||
private Object channelData;
|
||||
|
||||
/**
|
||||
* Get the type value.
|
||||
*
|
||||
* @return the type value
|
||||
*/
|
||||
public ActionTypes type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type value.
|
||||
*
|
||||
* @param type the type value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withType(ActionTypes type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title value.
|
||||
*
|
||||
* @return the title value
|
||||
*/
|
||||
public String title() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title value.
|
||||
*
|
||||
* @param title the title value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image value.
|
||||
*
|
||||
* @return the image value
|
||||
*/
|
||||
public String image() {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image value.
|
||||
*
|
||||
* @param image the image value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withImage(String image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value.
|
||||
*
|
||||
* @return the text value
|
||||
*/
|
||||
public String text() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text value.
|
||||
*
|
||||
* @param text the text value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayText value.
|
||||
*
|
||||
* @return the displayText value
|
||||
*/
|
||||
public String displayText() {
|
||||
return this.displayText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the displayText value.
|
||||
*
|
||||
* @param displayText the displayText value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withDisplayText(String displayText) {
|
||||
this.displayText = displayText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value value.
|
||||
*
|
||||
* @return the value value
|
||||
*/
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value value.
|
||||
*
|
||||
* @param value the value value to set
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withValue(Object value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the channelData value.
|
||||
*/
|
||||
public Object channelData(){
|
||||
return this.channelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the channelData value.
|
||||
*
|
||||
* @param channelData The channelData object to set.
|
||||
* @return the CardAction object itself.
|
||||
*/
|
||||
public CardAction withChannelData(Object channelData){
|
||||
this.channelData = channelData;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,97 +1,97 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* An image on a card.
|
||||
*/
|
||||
public class CardImage {
|
||||
/**
|
||||
* URL thumbnail image for major content property.
|
||||
*/
|
||||
@JsonProperty(value = "url")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* Image description intended for screen readers.
|
||||
*/
|
||||
@JsonProperty(value = "alt")
|
||||
private String alt;
|
||||
|
||||
/**
|
||||
* Action assigned to specific Attachment.
|
||||
*/
|
||||
@JsonProperty(value = "tap")
|
||||
private CardAction tap;
|
||||
|
||||
/**
|
||||
* Get the url value.
|
||||
*
|
||||
* @return the url value
|
||||
*/
|
||||
public String url() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the url value.
|
||||
*
|
||||
* @param url the url value to set
|
||||
* @return the CardImage object itself.
|
||||
*/
|
||||
public CardImage withUrl(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alt value.
|
||||
*
|
||||
* @return the alt value
|
||||
*/
|
||||
public String alt() {
|
||||
return this.alt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alt value.
|
||||
*
|
||||
* @param alt the alt value to set
|
||||
* @return the CardImage object itself.
|
||||
*/
|
||||
public CardImage withAlt(String alt) {
|
||||
this.alt = alt;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tap value.
|
||||
*
|
||||
* @return the tap value
|
||||
*/
|
||||
public CardAction tap() {
|
||||
return this.tap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tap value.
|
||||
*
|
||||
* @param tap the tap value to set
|
||||
* @return the CardImage object itself.
|
||||
*/
|
||||
public CardImage withTap(CardAction tap) {
|
||||
this.tap = tap;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* An image on a card.
|
||||
*/
|
||||
public class CardImage {
|
||||
/**
|
||||
* URL thumbnail image for major content property.
|
||||
*/
|
||||
@JsonProperty(value = "url")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* Image description intended for screen readers.
|
||||
*/
|
||||
@JsonProperty(value = "alt")
|
||||
private String alt;
|
||||
|
||||
/**
|
||||
* Action assigned to specific Attachment.
|
||||
*/
|
||||
@JsonProperty(value = "tap")
|
||||
private CardAction tap;
|
||||
|
||||
/**
|
||||
* Get the url value.
|
||||
*
|
||||
* @return the url value
|
||||
*/
|
||||
public String url() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the url value.
|
||||
*
|
||||
* @param url the url value to set
|
||||
* @return the CardImage object itself.
|
||||
*/
|
||||
public CardImage withUrl(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alt value.
|
||||
*
|
||||
* @return the alt value
|
||||
*/
|
||||
public String alt() {
|
||||
return this.alt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alt value.
|
||||
*
|
||||
* @param alt the alt value to set
|
||||
* @return the CardImage object itself.
|
||||
*/
|
||||
public CardImage withAlt(String alt) {
|
||||
this.alt = alt;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tap value.
|
||||
*
|
||||
* @return the tap value
|
||||
*/
|
||||
public CardAction tap() {
|
||||
return this.tap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tap value.
|
||||
*
|
||||
* @param tap the tap value to set
|
||||
* @return the CardImage object itself.
|
||||
*/
|
||||
public CardImage withTap(CardAction tap) {
|
||||
this.tap = tap;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,156 +1,156 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Channel account information needed to route a message.
|
||||
*/
|
||||
public class ChannelAccount {
|
||||
/**
|
||||
* Channel id for the user or bot on this channel (Example: joe@smith.com,
|
||||
* or @joesmith or 123456).
|
||||
*/
|
||||
@JsonProperty(value = "id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Display friendly name.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* This account's object ID within Azure Active Directory (AAD)
|
||||
*/
|
||||
@JsonProperty(value = "aadObjectId")
|
||||
private String aadObjectId;
|
||||
|
||||
/**
|
||||
* Role of the entity behind the account (Example: User, Bot, etc.).
|
||||
* Possible values include: 'user', 'bot'.
|
||||
*/
|
||||
@JsonProperty(value = "role")
|
||||
private RoleTypes role;
|
||||
|
||||
/**
|
||||
* Get the id value.
|
||||
*
|
||||
* @return the id value
|
||||
*/
|
||||
public String id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id value.
|
||||
*
|
||||
* @param id the id value to set
|
||||
* @return the ChannelAccount object itself.
|
||||
*/
|
||||
public ChannelAccount withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the ChannelAccount object itself.
|
||||
*/
|
||||
public ChannelAccount withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role value.
|
||||
*
|
||||
* @return the role value
|
||||
*/
|
||||
public RoleTypes role() {
|
||||
return this.role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the role value.
|
||||
*
|
||||
* @param role the role value to set
|
||||
* @return the ChannelAccount object itself.
|
||||
*/
|
||||
public ChannelAccount withRole(RoleTypes role) {
|
||||
this.role = role;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds the overflow properties that aren't first class
|
||||
* properties in the object. This allows extensibility
|
||||
* while maintaining the object.
|
||||
*
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
/**
|
||||
* Overflow properties.
|
||||
* Properties that are not modelled as first class properties in the object are accessible here.
|
||||
* Note: A property value can be be nested.
|
||||
*
|
||||
* @return A Key-Value map of the properties
|
||||
*/
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> properties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set overflow properties.
|
||||
*
|
||||
* @param key Key for the property
|
||||
* @param value JsonNode of value (can be nested)
|
||||
*
|
||||
*/
|
||||
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets aadObjectId
|
||||
*/
|
||||
public String aadObjectId(){
|
||||
return this.aadObjectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets aadObjectId
|
||||
*/
|
||||
public ChannelAccount withAadObjectId(String aadObjectId){
|
||||
this.aadObjectId = aadObjectId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Channel account information needed to route a message.
|
||||
*/
|
||||
public class ChannelAccount {
|
||||
/**
|
||||
* Channel id for the user or bot on this channel (Example: joe@smith.com,
|
||||
* or @joesmith or 123456).
|
||||
*/
|
||||
@JsonProperty(value = "id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Display friendly name.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* This account's object ID within Azure Active Directory (AAD)
|
||||
*/
|
||||
@JsonProperty(value = "aadObjectId")
|
||||
private String aadObjectId;
|
||||
|
||||
/**
|
||||
* Role of the entity behind the account (Example: User, Bot, etc.).
|
||||
* Possible values include: 'user', 'bot'.
|
||||
*/
|
||||
@JsonProperty(value = "role")
|
||||
private RoleTypes role;
|
||||
|
||||
/**
|
||||
* Get the id value.
|
||||
*
|
||||
* @return the id value
|
||||
*/
|
||||
public String id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id value.
|
||||
*
|
||||
* @param id the id value to set
|
||||
* @return the ChannelAccount object itself.
|
||||
*/
|
||||
public ChannelAccount withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the ChannelAccount object itself.
|
||||
*/
|
||||
public ChannelAccount withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role value.
|
||||
*
|
||||
* @return the role value
|
||||
*/
|
||||
public RoleTypes role() {
|
||||
return this.role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the role value.
|
||||
*
|
||||
* @param role the role value to set
|
||||
* @return the ChannelAccount object itself.
|
||||
*/
|
||||
public ChannelAccount withRole(RoleTypes role) {
|
||||
this.role = role;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds the overflow properties that aren't first class
|
||||
* properties in the object. This allows extensibility
|
||||
* while maintaining the object.
|
||||
*
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
/**
|
||||
* Overflow properties.
|
||||
* Properties that are not modelled as first class properties in the object are accessible here.
|
||||
* Note: A property value can be be nested.
|
||||
*
|
||||
* @return A Key-Value map of the properties
|
||||
*/
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> properties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set overflow properties.
|
||||
*
|
||||
* @param key Key for the property
|
||||
* @param value JsonNode of value (can be nested)
|
||||
*
|
||||
*/
|
||||
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets aadObjectId
|
||||
*/
|
||||
public String aadObjectId(){
|
||||
return this.aadObjectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets aadObjectId
|
||||
*/
|
||||
public ChannelAccount withAadObjectId(String aadObjectId){
|
||||
this.aadObjectId = aadObjectId;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,55 +1,55 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for ContactRelationUpdateActionTypes.
|
||||
*/
|
||||
public enum ContactRelationUpdateActionTypes {
|
||||
/** Enum value add. */
|
||||
ADD("add"),
|
||||
|
||||
/** Enum value remove. */
|
||||
REMOVE("remove");
|
||||
|
||||
/** The actual serialized value for a ContactRelationUpdateActionTypes instance. */
|
||||
private String value;
|
||||
|
||||
ContactRelationUpdateActionTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ContactRelationUpdateActionTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ContactRelationUpdateActionTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ContactRelationUpdateActionTypes fromString(String value) {
|
||||
ContactRelationUpdateActionTypes[] items = ContactRelationUpdateActionTypes.values();
|
||||
for (ContactRelationUpdateActionTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Defines values for ContactRelationUpdateActionTypes.
|
||||
*/
|
||||
public enum ContactRelationUpdateActionTypes {
|
||||
/** Enum value add. */
|
||||
ADD("add"),
|
||||
|
||||
/** Enum value remove. */
|
||||
REMOVE("remove");
|
||||
|
||||
/** The actual serialized value for a ContactRelationUpdateActionTypes instance. */
|
||||
private String value;
|
||||
|
||||
ContactRelationUpdateActionTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a serialized value to a ContactRelationUpdateActionTypes instance.
|
||||
*
|
||||
* @param value the serialized value to parse.
|
||||
* @return the parsed ContactRelationUpdateActionTypes object, or null if unable to parse.
|
||||
*/
|
||||
@JsonCreator
|
||||
public static ContactRelationUpdateActionTypes fromString(String value) {
|
||||
ContactRelationUpdateActionTypes[] items = ContactRelationUpdateActionTypes.values();
|
||||
for (ContactRelationUpdateActionTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
|
@ -1,231 +1,231 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Conversation account represents the identity of the conversation within a channel.
|
||||
*/
|
||||
public class ConversationAccount {
|
||||
/**
|
||||
* Indicates whether the conversation contains more than two participants
|
||||
* at the time the activity was generated.
|
||||
*/
|
||||
@JsonProperty(value = "isGroup")
|
||||
private Boolean isGroup;
|
||||
|
||||
/**
|
||||
* Indicates the type of the conversation in channels that distinguish
|
||||
* between conversation types.
|
||||
*/
|
||||
@JsonProperty(value = "conversationType")
|
||||
private String conversationType;
|
||||
|
||||
/**
|
||||
* This conversation's tenant ID.
|
||||
*/
|
||||
@JsonProperty(value = "tenantId")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* Channel id for the user or bot on this channel (Example: joe@smith.com,
|
||||
* or @joesmith or 123456).
|
||||
*/
|
||||
@JsonProperty(value = "id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Display friendly name.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* This account's object ID within Azure Active Directory (AAD).
|
||||
*/
|
||||
@JsonProperty(value = "aadObjectId")
|
||||
private String aadObjectId;
|
||||
|
||||
/**
|
||||
* Role of the entity behind the account (Example: User, Bot, etc.).
|
||||
* Possible values include: 'user', 'bot'.
|
||||
*/
|
||||
@JsonProperty(value = "role")
|
||||
private RoleTypes role;
|
||||
|
||||
/**
|
||||
* Get the isGroup value.
|
||||
*
|
||||
* @return the isGroup value
|
||||
*/
|
||||
public Boolean isGroup() {
|
||||
return this.isGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the isGroup value.
|
||||
*
|
||||
* @param isGroup the isGroup value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withIsGroup(Boolean isGroup) {
|
||||
this.isGroup = isGroup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the conversationType value.
|
||||
*
|
||||
* @return the conversationType value
|
||||
*/
|
||||
public String conversationType() {
|
||||
return this.conversationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the conversationType value.
|
||||
*
|
||||
* @param conversationType the conversationType value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withConversationType(String conversationType) {
|
||||
this.conversationType = conversationType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this conversation's tenant ID.
|
||||
*/
|
||||
public String tenantId(){
|
||||
return this.tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this conversation's tenant ID.
|
||||
*
|
||||
* @param tenantId this conversation's tenant ID
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withTenantId(String tenantId){
|
||||
this.tenantId = tenantId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id value.
|
||||
*
|
||||
* @return the id value
|
||||
*/
|
||||
public String id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id value.
|
||||
*
|
||||
* @param id the id value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this account's object ID within Azure Active Directory (AAD).
|
||||
*/
|
||||
public String aadObjectId(){
|
||||
return this.aadObjectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this account's object ID within Azure Active Directory (AAD).
|
||||
|
||||
* @param name the AAD ID to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withAadObjectId(String aadObjectId){
|
||||
this.aadObjectId = aadObjectId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role value.
|
||||
*
|
||||
* @return the role value
|
||||
*/
|
||||
public RoleTypes role() {
|
||||
return this.role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the role value.
|
||||
*
|
||||
* @param role the role value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withRole(RoleTypes role) {
|
||||
this.role = role;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Holds the overflow properties that aren't first class
|
||||
* properties in the object. This allows extensibility
|
||||
* while maintaining the object.
|
||||
*
|
||||
*/
|
||||
// private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
/**
|
||||
* Overflow properties.
|
||||
* Properties that are not modelled as first class properties in the object are accessible here.
|
||||
* Note: A property value can be be nested.
|
||||
*
|
||||
* @return A Key-Value map of the properties
|
||||
*/
|
||||
// @JsonAnyGetter
|
||||
// public Map<String, JsonNode> properties() {
|
||||
// return this.properties;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Set overflow properties.
|
||||
*
|
||||
* @param key Key for the property
|
||||
* @param value JsonNode of value (can be nested)
|
||||
*
|
||||
*/
|
||||
|
||||
// @JsonAnySetter
|
||||
// public void setProperties(String key, JsonNode value) {
|
||||
// this.properties.put(key, value);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Conversation account represents the identity of the conversation within a channel.
|
||||
*/
|
||||
public class ConversationAccount {
|
||||
/**
|
||||
* Indicates whether the conversation contains more than two participants
|
||||
* at the time the activity was generated.
|
||||
*/
|
||||
@JsonProperty(value = "isGroup")
|
||||
private Boolean isGroup;
|
||||
|
||||
/**
|
||||
* Indicates the type of the conversation in channels that distinguish
|
||||
* between conversation types.
|
||||
*/
|
||||
@JsonProperty(value = "conversationType")
|
||||
private String conversationType;
|
||||
|
||||
/**
|
||||
* This conversation's tenant ID.
|
||||
*/
|
||||
@JsonProperty(value = "tenantId")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* Channel id for the user or bot on this channel (Example: joe@smith.com,
|
||||
* or @joesmith or 123456).
|
||||
*/
|
||||
@JsonProperty(value = "id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Display friendly name.
|
||||
*/
|
||||
@JsonProperty(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* This account's object ID within Azure Active Directory (AAD).
|
||||
*/
|
||||
@JsonProperty(value = "aadObjectId")
|
||||
private String aadObjectId;
|
||||
|
||||
/**
|
||||
* Role of the entity behind the account (Example: User, Bot, etc.).
|
||||
* Possible values include: 'user', 'bot'.
|
||||
*/
|
||||
@JsonProperty(value = "role")
|
||||
private RoleTypes role;
|
||||
|
||||
/**
|
||||
* Get the isGroup value.
|
||||
*
|
||||
* @return the isGroup value
|
||||
*/
|
||||
public Boolean isGroup() {
|
||||
return this.isGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the isGroup value.
|
||||
*
|
||||
* @param isGroup the isGroup value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withIsGroup(Boolean isGroup) {
|
||||
this.isGroup = isGroup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the conversationType value.
|
||||
*
|
||||
* @return the conversationType value
|
||||
*/
|
||||
public String conversationType() {
|
||||
return this.conversationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the conversationType value.
|
||||
*
|
||||
* @param conversationType the conversationType value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withConversationType(String conversationType) {
|
||||
this.conversationType = conversationType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this conversation's tenant ID.
|
||||
*/
|
||||
public String tenantId(){
|
||||
return this.tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this conversation's tenant ID.
|
||||
*
|
||||
* @param tenantId this conversation's tenant ID
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withTenantId(String tenantId){
|
||||
this.tenantId = tenantId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id value.
|
||||
*
|
||||
* @return the id value
|
||||
*/
|
||||
public String id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id value.
|
||||
*
|
||||
* @param id the id value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name value.
|
||||
*
|
||||
* @return the name value
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name value.
|
||||
*
|
||||
* @param name the name value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this account's object ID within Azure Active Directory (AAD).
|
||||
*/
|
||||
public String aadObjectId(){
|
||||
return this.aadObjectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this account's object ID within Azure Active Directory (AAD).
|
||||
|
||||
* @param name the AAD ID to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withAadObjectId(String aadObjectId){
|
||||
this.aadObjectId = aadObjectId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role value.
|
||||
*
|
||||
* @return the role value
|
||||
*/
|
||||
public RoleTypes role() {
|
||||
return this.role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the role value.
|
||||
*
|
||||
* @param role the role value to set
|
||||
* @return the ConversationAccount object itself.
|
||||
*/
|
||||
public ConversationAccount withRole(RoleTypes role) {
|
||||
this.role = role;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Holds the overflow properties that aren't first class
|
||||
* properties in the object. This allows extensibility
|
||||
* while maintaining the object.
|
||||
*
|
||||
*/
|
||||
// private HashMap<String, JsonNode> properties = new HashMap<String, JsonNode>();
|
||||
|
||||
/**
|
||||
* Overflow properties.
|
||||
* Properties that are not modelled as first class properties in the object are accessible here.
|
||||
* Note: A property value can be be nested.
|
||||
*
|
||||
* @return A Key-Value map of the properties
|
||||
*/
|
||||
// @JsonAnyGetter
|
||||
// public Map<String, JsonNode> properties() {
|
||||
// return this.properties;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Set overflow properties.
|
||||
*
|
||||
* @param key Key for the property
|
||||
* @param value JsonNode of value (can be nested)
|
||||
*
|
||||
*/
|
||||
|
||||
// @JsonAnySetter
|
||||
// public void setProperties(String key, JsonNode value) {
|
||||
// this.properties.put(key, value);
|
||||
// }
|
||||
|
||||
|
||||
}
|
|
@ -1,72 +1,72 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Conversation and its members.
|
||||
*/
|
||||
public class ConversationMembers {
|
||||
/**
|
||||
* Conversation ID.
|
||||
*/
|
||||
@JsonProperty(value = "id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* List of members in this conversation.
|
||||
*/
|
||||
@JsonProperty(value = "members")
|
||||
private List<ChannelAccount> members;
|
||||
|
||||
/**
|
||||
* Get the id value.
|
||||
*
|
||||
* @return the id value
|
||||
*/
|
||||
public String id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id value.
|
||||
*
|
||||
* @param id the id value to set
|
||||
* @return the ConversationMembers object itself.
|
||||
*/
|
||||
public ConversationMembers withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the members value.
|
||||
*
|
||||
* @return the members value
|
||||
*/
|
||||
public List<ChannelAccount> members() {
|
||||
return this.members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the members value.
|
||||
*
|
||||
* @param members the members value to set
|
||||
* @return the ConversationMembers object itself.
|
||||
*/
|
||||
public ConversationMembers withMembers(List<ChannelAccount> members) {
|
||||
this.members = members;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Conversation and its members.
|
||||
*/
|
||||
public class ConversationMembers {
|
||||
/**
|
||||
* Conversation ID.
|
||||
*/
|
||||
@JsonProperty(value = "id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* List of members in this conversation.
|
||||
*/
|
||||
@JsonProperty(value = "members")
|
||||
private List<ChannelAccount> members;
|
||||
|
||||
/**
|
||||
* Get the id value.
|
||||
*
|
||||
* @return the id value
|
||||
*/
|
||||
public String id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id value.
|
||||
*
|
||||
* @param id the id value to set
|
||||
* @return the ConversationMembers object itself.
|
||||
*/
|
||||
public ConversationMembers withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the members value.
|
||||
*
|
||||
* @return the members value
|
||||
*/
|
||||
public List<ChannelAccount> members() {
|
||||
return this.members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the members value.
|
||||
*
|
||||
* @param members the members value to set
|
||||
* @return the ConversationMembers object itself.
|
||||
*/
|
||||
public ConversationMembers withMembers(List<ChannelAccount> members) {
|
||||
this.members = members;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,197 +1,197 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Parameters for creating a new conversation.
|
||||
*/
|
||||
public class ConversationParameters {
|
||||
/**
|
||||
* IsGroup.
|
||||
*/
|
||||
@JsonProperty(value = "isGroup")
|
||||
private Boolean isGroup;
|
||||
|
||||
/**
|
||||
* The bot address for this conversation.
|
||||
*/
|
||||
@JsonProperty(value = "bot")
|
||||
private ChannelAccount bot;
|
||||
|
||||
/**
|
||||
* Members to add to the conversation.
|
||||
*/
|
||||
@JsonProperty(value = "members")
|
||||
private List<ChannelAccount> members;
|
||||
|
||||
/**
|
||||
* (Optional) Topic of the conversation (if supported by the channel).
|
||||
*/
|
||||
@JsonProperty(value = "topicName")
|
||||
private String topicName;
|
||||
|
||||
/**
|
||||
* (Optional) The tenant ID in which the conversation should be created.
|
||||
*/
|
||||
@JsonProperty(value = "tenantId")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* (Optional) When creating a new conversation, use this activity as the
|
||||
* intial message to the conversation.
|
||||
*/
|
||||
@JsonProperty(value = "activity")
|
||||
private Activity activity;
|
||||
|
||||
/**
|
||||
* Channel specific payload for creating the conversation.
|
||||
*/
|
||||
@JsonProperty(value = "channelData")
|
||||
private Object channelData;
|
||||
|
||||
/**
|
||||
* Get the isGroup value.
|
||||
*
|
||||
* @return the isGroup value
|
||||
*/
|
||||
public Boolean isGroup() {
|
||||
return this.isGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the isGroup value.
|
||||
*
|
||||
* @param isGroup the isGroup value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withIsGroup(Boolean isGroup) {
|
||||
this.isGroup = isGroup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bot value.
|
||||
*
|
||||
* @return the bot value
|
||||
*/
|
||||
public ChannelAccount bot() {
|
||||
return this.bot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bot value.
|
||||
*
|
||||
* @param bot the bot value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withBot(ChannelAccount bot) {
|
||||
this.bot = bot;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the members value.
|
||||
*
|
||||
* @return the members value
|
||||
*/
|
||||
public List<ChannelAccount> members() {
|
||||
return this.members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the members value.
|
||||
*
|
||||
* @param members the members value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withMembers(List<ChannelAccount> members) {
|
||||
this.members = members;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the topicName value.
|
||||
*
|
||||
* @return the topicName value
|
||||
*/
|
||||
public String topicName() {
|
||||
return this.topicName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the topicName value.
|
||||
*
|
||||
* @param topicName the topicName value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity value.
|
||||
*
|
||||
* @return the activity value
|
||||
*/
|
||||
public Activity activity() {
|
||||
return this.activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the activity value.
|
||||
*
|
||||
* @param activity the activity value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withActivity(Activity activity) {
|
||||
this.activity = activity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channelData value.
|
||||
*
|
||||
* @return the channelData value
|
||||
*/
|
||||
public Object channelData() {
|
||||
return this.channelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channelData value.
|
||||
*
|
||||
* @param channelData the channelData value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withChannelData(Object channelData) {
|
||||
this.channelData = channelData;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets tenantId
|
||||
*/
|
||||
public String tenantId(){
|
||||
return this.tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets tenantId
|
||||
*/
|
||||
public ConversationParameters withTenantId(String tenantId){
|
||||
this.tenantId = tenantId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema.models;
|
||||
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Parameters for creating a new conversation.
|
||||
*/
|
||||
public class ConversationParameters {
|
||||
/**
|
||||
* IsGroup.
|
||||
*/
|
||||
@JsonProperty(value = "isGroup")
|
||||
private Boolean isGroup;
|
||||
|
||||
/**
|
||||
* The bot address for this conversation.
|
||||
*/
|
||||
@JsonProperty(value = "bot")
|
||||
private ChannelAccount bot;
|
||||
|
||||
/**
|
||||
* Members to add to the conversation.
|
||||
*/
|
||||
@JsonProperty(value = "members")
|
||||
private List<ChannelAccount> members;
|
||||
|
||||
/**
|
||||
* (Optional) Topic of the conversation (if supported by the channel).
|
||||
*/
|
||||
@JsonProperty(value = "topicName")
|
||||
private String topicName;
|
||||
|
||||
/**
|
||||
* (Optional) The tenant ID in which the conversation should be created.
|
||||
*/
|
||||
@JsonProperty(value = "tenantId")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* (Optional) When creating a new conversation, use this activity as the
|
||||
* intial message to the conversation.
|
||||
*/
|
||||
@JsonProperty(value = "activity")
|
||||
private Activity activity;
|
||||
|
||||
/**
|
||||
* Channel specific payload for creating the conversation.
|
||||
*/
|
||||
@JsonProperty(value = "channelData")
|
||||
private Object channelData;
|
||||
|
||||
/**
|
||||
* Get the isGroup value.
|
||||
*
|
||||
* @return the isGroup value
|
||||
*/
|
||||
public Boolean isGroup() {
|
||||
return this.isGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the isGroup value.
|
||||
*
|
||||
* @param isGroup the isGroup value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withIsGroup(Boolean isGroup) {
|
||||
this.isGroup = isGroup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bot value.
|
||||
*
|
||||
* @return the bot value
|
||||
*/
|
||||
public ChannelAccount bot() {
|
||||
return this.bot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bot value.
|
||||
*
|
||||
* @param bot the bot value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withBot(ChannelAccount bot) {
|
||||
this.bot = bot;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the members value.
|
||||
*
|
||||
* @return the members value
|
||||
*/
|
||||
public List<ChannelAccount> members() {
|
||||
return this.members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the members value.
|
||||
*
|
||||
* @param members the members value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withMembers(List<ChannelAccount> members) {
|
||||
this.members = members;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the topicName value.
|
||||
*
|
||||
* @return the topicName value
|
||||
*/
|
||||
public String topicName() {
|
||||
return this.topicName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the topicName value.
|
||||
*
|
||||
* @param topicName the topicName value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity value.
|
||||
*
|
||||
* @return the activity value
|
||||
*/
|
||||
public Activity activity() {
|
||||
return this.activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the activity value.
|
||||
*
|
||||
* @param activity the activity value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withActivity(Activity activity) {
|
||||
this.activity = activity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channelData value.
|
||||
*
|
||||
* @return the channelData value
|
||||
*/
|
||||
public Object channelData() {
|
||||
return this.channelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channelData value.
|
||||
*
|
||||
* @param channelData the channelData value to set
|
||||
* @return the ConversationParameters object itself.
|
||||
*/
|
||||
public ConversationParameters withChannelData(Object channelData) {
|
||||
this.channelData = channelData;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets tenantId
|
||||
*/
|
||||
public String tenantId(){
|
||||
return this.tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets tenantId
|
||||
*/
|
||||
public ConversationParameters withTenantId(String tenantId){
|
||||
this.tenantId = tenantId;
|
||||
return this;
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче