Added Event Factory for handoff protocol (#1118)
* Added Event Factory for handoff protocol * Added additional unit test. Co-authored-by: tracyboehrer <tracyboehrer@users.noreply.github.com>
This commit is contained in:
Родитель
42edeb37d3
Коммит
45130e6ae7
|
@ -0,0 +1,134 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.microsoft.bot.schema.Activity;
|
||||
import com.microsoft.bot.schema.Attachment;
|
||||
import com.microsoft.bot.schema.ConversationAccount;
|
||||
import com.microsoft.bot.schema.Entity;
|
||||
import com.microsoft.bot.schema.HandoffEventNames;
|
||||
import com.microsoft.bot.schema.Transcript;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Contains utility methods for creating various event types.
|
||||
*/
|
||||
public final class EventFactory {
|
||||
|
||||
private EventFactory() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create handoff initiation event.
|
||||
*
|
||||
* @param turnContext turn context.
|
||||
* @param handoffContext agent hub-specific context.
|
||||
*
|
||||
* @return handoff event.
|
||||
*/
|
||||
public static Activity createHandoffInitiation(TurnContext turnContext, Object handoffContext) {
|
||||
return createHandoffInitiation(turnContext, handoffContext, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create handoff initiation event.
|
||||
*
|
||||
* @param turnContext turn context.
|
||||
* @param handoffContext agent hub-specific context.
|
||||
* @param transcript transcript of the conversation.
|
||||
*
|
||||
* @return handoff event.
|
||||
*/
|
||||
public static Activity createHandoffInitiation(TurnContext turnContext, Object handoffContext,
|
||||
Transcript transcript) {
|
||||
if (turnContext == null) {
|
||||
throw new IllegalArgumentException("turnContext cannot be null.");
|
||||
}
|
||||
|
||||
Activity handoffEvent = createHandoffEvent(HandoffEventNames.INITIATEHANDOFF, handoffContext,
|
||||
turnContext.getActivity().getConversation());
|
||||
|
||||
handoffEvent.setFrom(turnContext.getActivity().getFrom());
|
||||
handoffEvent.setRelatesTo(turnContext.getActivity().getConversationReference());
|
||||
handoffEvent.setReplyToId(turnContext.getActivity().getId());
|
||||
handoffEvent.setServiceUrl(turnContext.getActivity().getServiceUrl());
|
||||
handoffEvent.setChannelId(turnContext.getActivity().getChannelId());
|
||||
|
||||
if (transcript != null) {
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.setContent(transcript);
|
||||
attachment.setContentType("application/json");
|
||||
attachment.setName("Transcript");
|
||||
handoffEvent.getAttachments().add(attachment);
|
||||
}
|
||||
|
||||
return handoffEvent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create handoff status event.
|
||||
*
|
||||
* @param conversation Conversation being handed over.
|
||||
* @param state State, possible values are: "accepted", "failed",
|
||||
* "completed".
|
||||
*
|
||||
* @return handoff event.
|
||||
*/
|
||||
public static Activity createHandoffStatus(ConversationAccount conversation, String state) {
|
||||
return createHandoffStatus(conversation, state, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create handoff status event.
|
||||
*
|
||||
* @param conversation Conversation being handed over.
|
||||
* @param state State, possible values are: "accepted", "failed",
|
||||
* "completed".
|
||||
* @param message Additional message for failed handoff.
|
||||
*
|
||||
* @return handoff event.
|
||||
*/
|
||||
public static Activity createHandoffStatus(ConversationAccount conversation, String state, String message) {
|
||||
if (conversation == null) {
|
||||
throw new IllegalArgumentException("conversation cannot be null.");
|
||||
}
|
||||
|
||||
if (state == null) {
|
||||
throw new IllegalArgumentException("state cannot be null.");
|
||||
}
|
||||
|
||||
ObjectNode handoffContext = JsonNodeFactory.instance.objectNode();
|
||||
handoffContext.set("state", JsonNodeFactory.instance.textNode(state));
|
||||
if (StringUtils.isNotBlank(message)) {
|
||||
handoffContext.set("message", JsonNodeFactory.instance.textNode(message));
|
||||
}
|
||||
|
||||
Activity handoffEvent = createHandoffEvent(HandoffEventNames.HANDOFFSTATUS, handoffContext, conversation);
|
||||
return handoffEvent;
|
||||
}
|
||||
|
||||
private static Activity createHandoffEvent(String name, Object value, ConversationAccount conversation) {
|
||||
Activity handoffEvent = Activity.createEventActivity();
|
||||
|
||||
handoffEvent.setName(name);
|
||||
handoffEvent.setValue(value);
|
||||
handoffEvent.setId(UUID.randomUUID().toString());
|
||||
handoffEvent.setTimestamp(OffsetDateTime.now(ZoneId.of("UTC")));
|
||||
handoffEvent.setConversation(conversation);
|
||||
handoffEvent.setAttachments(new ArrayList<Attachment>());
|
||||
handoffEvent.setEntities(new ArrayList<Entity>());
|
||||
return handoffEvent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.microsoft.bot.builder.adapters.TestAdapter;
|
||||
import com.microsoft.bot.schema.Activity;
|
||||
import com.microsoft.bot.schema.ActivityTypes;
|
||||
import com.microsoft.bot.schema.ChannelAccount;
|
||||
import com.microsoft.bot.schema.ConversationAccount;
|
||||
import com.microsoft.bot.schema.HandoffEventNames;
|
||||
import com.microsoft.bot.schema.Serialization;
|
||||
import com.microsoft.bot.schema.Transcript;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class EventFactoryTests {
|
||||
|
||||
@Test
|
||||
public void HandoffInitiationNullTurnContext() {
|
||||
Assert.assertThrows(IllegalArgumentException.class,
|
||||
() -> EventFactory.createHandoffInitiation(null, "some text"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HandoffStatusNullConversation() {
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> EventFactory.createHandoffStatus(null, "accepted"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HandoffStatusNullStatus() {
|
||||
Assert.assertThrows(IllegalArgumentException.class,
|
||||
() -> EventFactory.createHandoffStatus(new ConversationAccount(), null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCreateHandoffInitiation() {
|
||||
TestAdapter adapter = new TestAdapter(
|
||||
TestAdapter.createConversationReference("TestCreateHandoffInitiation", "User1", "Bot"));
|
||||
String fromD = "test";
|
||||
Activity activity = new Activity(ActivityTypes.MESSAGE);
|
||||
activity.setText("");
|
||||
activity.setConversation(new ConversationAccount());
|
||||
activity.setRecipient(new ChannelAccount());
|
||||
activity.setFrom(new ChannelAccount(fromD));
|
||||
activity.setChannelId("testchannel");
|
||||
activity.setServiceUrl("http://myservice");
|
||||
TurnContext context = new TurnContextImpl(adapter, activity);
|
||||
List<Activity> activities = new ArrayList<Activity>();
|
||||
activities.add(MessageFactory.text("hello"));
|
||||
Transcript transcript = new Transcript();
|
||||
transcript.setActivities(activities);
|
||||
|
||||
Assert.assertNull(transcript.getActivities().get(0).getChannelId());
|
||||
Assert.assertNull(transcript.getActivities().get(0).getServiceUrl());
|
||||
Assert.assertNull(transcript.getActivities().get(0).getConversation());
|
||||
|
||||
ObjectNode handoffContext = JsonNodeFactory.instance.objectNode();
|
||||
handoffContext.set("Skill", JsonNodeFactory.instance.textNode("any"));
|
||||
|
||||
Activity handoffEvent = EventFactory.createHandoffInitiation(context, handoffContext, transcript);
|
||||
Assert.assertEquals(handoffEvent.getName(), HandoffEventNames.INITIATEHANDOFF);
|
||||
ObjectNode node = (ObjectNode) handoffEvent.getValue();
|
||||
String skill = node.get("Skill").asText();
|
||||
Assert.assertEquals("any", skill);
|
||||
Assert.assertEquals(handoffEvent.getFrom().getId(), fromD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCreateHandoffInitiationNoTranscript() {
|
||||
TestAdapter adapter = new TestAdapter(
|
||||
TestAdapter.createConversationReference("TestCreateHandoffInitiation", "User1", "Bot"));
|
||||
String fromD = "test";
|
||||
Activity activity = new Activity(ActivityTypes.MESSAGE);
|
||||
activity.setText("");
|
||||
activity.setConversation(new ConversationAccount());
|
||||
activity.setRecipient(new ChannelAccount());
|
||||
activity.setFrom(new ChannelAccount(fromD));
|
||||
activity.setChannelId("testchannel");
|
||||
activity.setServiceUrl("http://myservice");
|
||||
TurnContext context = new TurnContextImpl(adapter, activity);
|
||||
List<Activity> activities = new ArrayList<Activity>();
|
||||
activities.add(MessageFactory.text("hello"));
|
||||
|
||||
ObjectNode handoffContext = JsonNodeFactory.instance.objectNode();
|
||||
handoffContext.set("Skill", JsonNodeFactory.instance.textNode("any"));
|
||||
|
||||
Activity handoffEvent = EventFactory.createHandoffInitiation(context, handoffContext);
|
||||
Assert.assertEquals(handoffEvent.getName(), HandoffEventNames.INITIATEHANDOFF);
|
||||
ObjectNode node = (ObjectNode) handoffEvent.getValue();
|
||||
String skill = node.get("Skill").asText();
|
||||
Assert.assertEquals("any", skill);
|
||||
Assert.assertEquals(handoffEvent.getFrom().getId(), fromD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCreateHandoffStatus() throws JsonProcessingException {
|
||||
String state = "failed";
|
||||
String message = "timed out";
|
||||
Activity handoffEvent = EventFactory.createHandoffStatus(new ConversationAccount(), state, message);
|
||||
Assert.assertEquals(handoffEvent.getName(), HandoffEventNames.HANDOFFSTATUS);
|
||||
|
||||
ObjectNode node = (ObjectNode) handoffEvent.getValue();
|
||||
|
||||
String stateFormEvent = node.get("state").asText();
|
||||
Assert.assertEquals(stateFormEvent, state);
|
||||
|
||||
String messageFormEvent = node.get("message").asText();
|
||||
Assert.assertEquals(messageFormEvent, message);
|
||||
|
||||
String status = Serialization.toString(node);
|
||||
Assert.assertEquals(status, String.format("{\"state\":\"%s\",\"message\":\"%s\"}", state, message));
|
||||
Assert.assertNotNull(handoffEvent.getAttachments());
|
||||
Assert.assertNotNull(handoffEvent.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCreateHandoffStatusNoMessage() {
|
||||
String state = "failed";
|
||||
Activity handoffEvent = EventFactory.createHandoffStatus(new ConversationAccount(), state);
|
||||
|
||||
ObjectNode node = (ObjectNode) handoffEvent.getValue();
|
||||
|
||||
String stateFormEvent = node.get("state").asText();
|
||||
Assert.assertEquals(stateFormEvent, state);
|
||||
|
||||
JsonNode messageFormEvent = node.get("message");
|
||||
Assert.assertNull(messageFormEvent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.schema;
|
||||
|
||||
/**
|
||||
* Defines values for handoff event names.
|
||||
*/
|
||||
public final class HandoffEventNames {
|
||||
|
||||
private HandoffEventNames() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of handoff events for initiate handoff.
|
||||
*/
|
||||
public static final String INITIATEHANDOFF = "handoff.initiate";
|
||||
|
||||
/**
|
||||
* The value of handoff events for handoff status.
|
||||
*/
|
||||
public static final String HANDOFFSTATUS = "handoff.status";
|
||||
}
|
Загрузка…
Ссылка в новой задаче