Implemented BotFrameworkAdapter OAuth methods. More cleanup.

This commit is contained in:
Tracy Boehrer 2019-09-27 09:54:15 -05:00
Родитель 08589b677f
Коммит 111d631e72
20 изменённых файлов: 263 добавлений и 191 удалений

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

@ -125,12 +125,10 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId> <artifactId>maven-pmd-plugin</artifactId>
<configuration> </plugin>
<analysisCache>true</analysisCache> <plugin>
<excludes> <groupId>org.apache.maven.plugins</groupId>
<exclude>**/**</exclude> <artifactId>maven-checkstyle-plugin</artifactId>
</excludes>
</configuration>
</plugin> </plugin>
<plugin> <plugin>

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

@ -97,18 +97,18 @@ public class ActivityHandler implements Bot {
protected CompletableFuture<Void> onConversationUpdateActivity(TurnContext turnContext) { protected CompletableFuture<Void> onConversationUpdateActivity(TurnContext turnContext) {
Activity activity = turnContext.getActivity(); Activity activity = turnContext.getActivity();
if (activity.getMembersAdded() != null) { if (activity.getMembersAdded() != null
if (activity.getRecipient() != null && activity.getMembersAdded().stream() && activity.getRecipient() != null
.anyMatch(m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) { && activity.getMembersAdded().stream().anyMatch(
m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) {
return onMembersAdded(activity.getMembersAdded(), turnContext); return onMembersAdded(activity.getMembersAdded(), turnContext);
} } else if (activity.getMembersRemoved() != null
} else if (activity.getRecipient() != null && activity.getMembersRemoved() != null) { && activity.getRecipient() != null
if (activity.getMembersRemoved().stream() && activity.getMembersRemoved().stream()
.anyMatch(m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) { .anyMatch(m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) {
return onMembersRemoved(activity.getMembersRemoved(), turnContext); return onMembersRemoved(activity.getMembersRemoved(), turnContext);
}
} }
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);

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

@ -7,13 +7,36 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.BaseEncoding; import com.google.common.io.BaseEncoding;
import com.microsoft.bot.builder.integration.AdapterIntegration; import com.microsoft.bot.builder.integration.AdapterIntegration;
import com.microsoft.bot.connector.*; import com.microsoft.bot.connector.Channels;
import com.microsoft.bot.connector.authentication.*; import com.microsoft.bot.connector.ConnectorClient;
import com.microsoft.bot.connector.Conversations;
import com.microsoft.bot.connector.ExecutorFactory;
import com.microsoft.bot.connector.OAuthClient;
import com.microsoft.bot.connector.OAuthClientConfig;
import com.microsoft.bot.connector.authentication.AuthenticationConfiguration;
import com.microsoft.bot.connector.authentication.AuthenticationConstants;
import com.microsoft.bot.connector.authentication.ChannelProvider;
import com.microsoft.bot.connector.authentication.ClaimsIdentity;
import com.microsoft.bot.connector.authentication.CredentialProvider;
import com.microsoft.bot.connector.authentication.JwtTokenValidation;
import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials;
import com.microsoft.bot.connector.rest.RestConnectorClient; import com.microsoft.bot.connector.rest.RestConnectorClient;
import com.microsoft.bot.connector.rest.RestOAuthClient; import com.microsoft.bot.connector.rest.RestOAuthClient;
import com.microsoft.bot.schema.*; import com.microsoft.bot.schema.AadResourceUrls;
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.ConversationParameters;
import com.microsoft.bot.schema.ConversationReference;
import com.microsoft.bot.schema.ConversationResourceResponse;
import com.microsoft.bot.schema.ConversationsResult;
import com.microsoft.bot.schema.ResourceResponse;
import com.microsoft.bot.schema.RoleTypes;
import com.microsoft.bot.schema.TokenExchangeState;
import com.microsoft.bot.schema.TokenResponse;
import com.microsoft.bot.schema.TokenStatus;
import com.microsoft.rest.retry.RetryStrategy; import com.microsoft.rest.retry.RetryStrategy;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.net.MalformedURLException; import java.net.MalformedURLException;
@ -28,8 +51,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static java.util.concurrent.CompletableFuture.completedFuture;
/** /**
* A bot adapter that can connect a bot to a service endpoint. * A bot adapter that can connect a bot to a service endpoint.
* *
@ -50,8 +71,19 @@ import static java.util.concurrent.CompletableFuture.completedFuture;
* {@link Middleware} * {@link Middleware}
*/ */
public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegration, UserTokenProvider { public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegration, UserTokenProvider {
/**
* Key to store Activity to match .Net.
*/
private static final String INVOKE_RESPONSE_KEY = "BotFrameworkAdapter.InvokeResponse"; private static final String INVOKE_RESPONSE_KEY = "BotFrameworkAdapter.InvokeResponse";
/**
* Key to store bot claims identity to match .Net.
*/
private static final String BOT_IDENTITY_KEY = "BotIdentity"; private static final String BOT_IDENTITY_KEY = "BotIdentity";
/**
* Key to store ConnectorClient to match .Net.
*/
private static final String CONNECTOR_CLIENT_KEY = "ConnectorClient"; private static final String CONNECTOR_CLIENT_KEY = "ConnectorClient";
/** /**
@ -277,7 +309,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
if (invokeResponse == null) { if (invokeResponse == null) {
throw new IllegalStateException("Bot failed to return a valid 'invokeResponse' activity."); throw new IllegalStateException("Bot failed to return a valid 'invokeResponse' activity.");
} else { } else {
return completedFuture((InvokeResponse) invokeResponse.getValue()); return CompletableFuture.completedFuture((InvokeResponse) invokeResponse.getValue());
} }
} }
@ -324,7 +356,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
*/ */
for (int index = 0; index < activities.size(); index++) { for (int index = 0; index < activities.size(); index++) {
Activity activity = activities.get(index); Activity activity = activities.get(index);
ResourceResponse response = null; ResourceResponse response;
if (activity.isType(ActivityTypes.DELAY)) { if (activity.isType(ActivityTypes.DELAY)) {
// The Activity Schema doesn't have a delay type build in, so it's simulated // The Activity Schema doesn't have a delay type build in, so it's simulated
@ -336,12 +368,15 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new RuntimeException(e); throw new RuntimeException(e);
} }
// No need to create a response. One will be created below. // No need to create a response. One will be created below.
response = null;
} else if (activity.isType(ActivityTypes.INVOKE_RESPONSE)) { } else if (activity.isType(ActivityTypes.INVOKE_RESPONSE)) {
context.getTurnState().add(INVOKE_RESPONSE_KEY, activity); context.getTurnState().add(INVOKE_RESPONSE_KEY, activity);
// No need to create a response. One will be created below. // No need to create a response. One will be created below.
response = null;
} else if (activity.isType(ActivityTypes.TRACE) } else if (activity.isType(ActivityTypes.TRACE)
&& !StringUtils.equals(activity.getChannelId(), Channels.EMULATOR)) { && !StringUtils.equals(activity.getChannelId(), Channels.EMULATOR)) {
// if it is a Trace activity we only send to the channel if it's the emulator. // if it is a Trace activity we only send to the channel if it's the emulator.
response = null;
} else if (!StringUtils.isEmpty(activity.getReplyToId())) { } else if (!StringUtils.isEmpty(activity.getReplyToId())) {
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY); ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
response = connectorClient.getConversations().replyToActivity(activity).join(); response = connectorClient.getConversations().replyToActivity(activity).join();
@ -454,7 +489,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation"); throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation");
} }
if (StringUtils.isEmpty((context.getActivity().getConversation().getId()))) { if (StringUtils.isEmpty(context.getActivity().getConversation().getId())) {
throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation.id"); throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation.id");
} }
@ -594,18 +629,14 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("connectionName"); throw new IllegalArgumentException("connectionName");
} }
CompletableFuture<TokenResponse> result = new CompletableFuture<>(); return createOAuthClient(context)
.thenCompose(oAuthClient -> {
try { return oAuthClient.getUserToken().getToken(
// TODO: getUserToken context.getActivity().getFrom().getId(),
// OAuthClientOld client = createOAuthApiClient(context); connectionName,
// return client.getUserToken(context.getActivity().getFrom().getId(), connectionName, magicCode); context.getActivity().getChannelId(),
result.completeExceptionally(new NotImplementedException("getUserToken")); magicCode);
return result; });
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
} }
/** /**
@ -622,40 +653,36 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("connectionName"); throw new IllegalArgumentException("connectionName");
} }
CompletableFuture<String> result = new CompletableFuture<>(); return createOAuthClient(context)
.thenCompose(oAuthClient -> {
try {
Activity activity = context.getActivity();
try { TokenExchangeState tokenExchangeState = new TokenExchangeState() {{
Activity activity = context.getActivity(); setConnectionName(connectionName);
setConversation(new ConversationReference(){{
setActivityId(activity.getId());
setBot(activity.getRecipient());
setChannelId(activity.getChannelId());
setConversation(activity.getConversation());
setServiceUrl(activity.getServiceUrl());
setUser(activity.getFrom());
}});
TokenExchangeState tokenExchangeState = new TokenExchangeState() {{ // TODO: on what planet would this ever be valid (from dotnet)?
setConnectionName(connectionName); //MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId,
setConversation(new ConversationReference(){{ }};
setActivityId(activity.getId());
setBot(activity.getRecipient());
setChannelId(activity.getChannelId());
setConversation(activity.getConversation());
setServiceUrl(activity.getServiceUrl());
setUser(activity.getFrom());
}});
// TODO: on what planet would this ever be valid (from dotnet)? ObjectMapper mapper = new ObjectMapper();
//MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId, String serializedState = mapper.writeValueAsString(tokenExchangeState);
}}; byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8);
String state = BaseEncoding.base64().encode(encodedState);
ObjectMapper mapper = new ObjectMapper(); return oAuthClient.getBotSignIn().getSignInUrl(state);
String serializedState = mapper.writeValueAsString(tokenExchangeState); } catch (Throwable t) {
byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8); throw new CompletionException(t);
String state = BaseEncoding.base64().encode(encodedState); }
});
// TODO: getOauthSignInLink
// ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl());
// return client.getBotSignIn().getSignInUrl(state);
result.completeExceptionally(new NotImplementedException("getOauthSignInLink"));
return result;
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
} }
/** /**
@ -664,7 +691,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
* @param context Context for the current turn of conversation with the user. * @param context Context for the current turn of conversation with the user.
* @param connectionName Name of the auth connection to use. * @param connectionName Name of the auth connection to use.
* @param userId The user id that will be associated with the token. * @param userId The user id that will be associated with the token.
* @param finalRedirect * @param finalRedirect The final URL that the OAuth flow will redirect to.
* @return A task that represents the work queued to execute. * @return A task that represents the work queued to execute.
*/ */
@Override @Override
@ -681,43 +708,39 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("userId"); throw new IllegalArgumentException("userId");
} }
CompletableFuture<String> result = new CompletableFuture<>(); return createOAuthClient(context)
.thenCompose(oAuthClient -> {
try {
TokenExchangeState tokenExchangeState = new TokenExchangeState() {{
setConnectionName(connectionName);
setConversation(new ConversationReference(){{
setActivityId(null);
setBot(new ChannelAccount() {{
setRole(RoleTypes.BOT);
}});
setChannelId(Channels.DIRECTLINE);
setConversation(new ConversationAccount());
setServiceUrl(null);
setUser(new ChannelAccount() {{
setRole(RoleTypes.USER);
setId(userId);
}});
}});
try { // TODO: on what planet would this ever be valid (from dotnet)?
TokenExchangeState tokenExchangeState = new TokenExchangeState() {{ //MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId,
setConnectionName(connectionName); }};
setConversation(new ConversationReference(){{
setActivityId(null);
setBot(new ChannelAccount() {{
setRole(RoleTypes.BOT);
}});
setChannelId(Channels.DIRECTLINE);
setConversation(new ConversationAccount());
setServiceUrl(null);
setUser(new ChannelAccount() {{
setRole(RoleTypes.USER);
setId(userId);
}});
}});
// TODO: on what planet would this ever be valid (from dotnet)? ObjectMapper mapper = new ObjectMapper();
//MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId, String serializedState = mapper.writeValueAsString(tokenExchangeState);
}}; byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8);
String state = BaseEncoding.base64().encode(encodedState);
ObjectMapper mapper = new ObjectMapper(); return oAuthClient.getBotSignIn().getSignInUrl(state);
String serializedState = mapper.writeValueAsString(tokenExchangeState); } catch (Throwable t) {
byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8); throw new CompletionException(t);
String state = BaseEncoding.base64().encode(encodedState); }
});
// TODO: getOauthSignInLink
// ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl());
// return client.getBotSignIn().getSignInUrl(state);
result.completeExceptionally(new NotImplementedException("getOauthSignInLink"));
return result;
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
} }
/** /**
@ -734,18 +757,12 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("connectionName"); throw new IllegalArgumentException("connectionName");
} }
CompletableFuture<Void> result = new CompletableFuture<>(); return createOAuthClient(context)
.thenCompose(oAuthClient -> {
try { return oAuthClient.getUserToken().signOut(
// TODO: signoutUser context.getActivity().getFrom().getId(), connectionName, context.getActivity().getChannelId());
//ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl()); })
//return client.signOutUser(context.getActivity().getFrom().getId(), connectionName); .thenApply(signOutResult -> null);
result.completeExceptionally(new NotImplementedException("signOutUser"));
return result;
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
} }
/** /**
@ -753,20 +770,24 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
* *
* @param context Context for the current turn of conversation with the user. * @param context Context for the current turn of conversation with the user.
* @param userId The user Id for which token status is retrieved. * @param userId The user Id for which token status is retrieved.
* @param includeFilter * @param includeFilter Optional comma separated list of connection's to include.
* Blank will return token status for all configured connections.
* @return Array of {@link TokenStatus}. * @return Array of {@link TokenStatus}.
*/ */
@Override @Override
public CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext context, String userId, String includeFilter) { public CompletableFuture<List<TokenStatus>> getTokenStatus(TurnContext context,
String userId,
String includeFilter) {
BotAssert.contextNotNull(context); BotAssert.contextNotNull(context);
if (StringUtils.isEmpty(userId)) { if (StringUtils.isEmpty(userId)) {
throw new IllegalArgumentException("userId"); throw new IllegalArgumentException("userId");
} }
// TODO: getTokenStatus return createOAuthClient(context)
CompletableFuture<TokenStatus[]> result = new CompletableFuture<>(); .thenCompose(oAuthClient -> {
result.completeExceptionally(new NotImplementedException("getTokenStatus")); return oAuthClient.getUserToken().getTokenStatus(
return result; userId, context.getActivity().getChannelId(), includeFilter);
});
} }
/** /**
@ -793,17 +814,19 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("resourceUrls"); throw new IllegalArgumentException("resourceUrls");
} }
String effectiveUserId = userId; return createOAuthClient(context)
if (StringUtils.isEmpty(effectiveUserId)) { .thenCompose(oAuthClient -> {
if (context.getActivity() != null && context.getActivity().getFrom() != null) { String effectiveUserId = userId;
effectiveUserId = context.getActivity().getFrom().getId(); if (StringUtils.isEmpty(effectiveUserId)
} && context.getActivity() != null
} && context.getActivity().getFrom() != null) {
// TODO: getAadTokens effectiveUserId = context.getActivity().getFrom().getId();
CompletableFuture<Map<String, TokenResponse>> result = new CompletableFuture<>(); }
result.completeExceptionally(new NotImplementedException("getAadTokens"));
return result; return oAuthClient.getUserToken().getAadTokens(
effectiveUserId, connectionName, new AadResourceUrls(resourceUrls));
});
} }
/** /**
@ -832,7 +855,6 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
MicrosoftAppCredentials credentials, MicrosoftAppCredentials credentials,
ConversationParameters conversationParameters, ConversationParameters conversationParameters,
BotCallbackHandler callback) { BotCallbackHandler callback) {
// TODO: all these joins are gross
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
ConnectorClient connectorClient; ConnectorClient connectorClient;
try { try {

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

@ -96,7 +96,8 @@ public abstract class BotState implements PropertyManager {
if (force || cachedState == null || cachedState.getState() == null) { if (force || cachedState == null || cachedState.getState() == null) {
return storage.read(new String[]{storageKey}) return storage.read(new String[]{storageKey})
.thenApply(val -> { .thenApply(val -> {
turnContext.getTurnState().replace(contextServiceKey, new CachedBotState((Map<String, Object>)val.get(storageKey))); turnContext.getTurnState().replace(
contextServiceKey, new CachedBotState((Map<String, Object>) val.get(storageKey)));
return null; return null;
}); });
} }
@ -128,7 +129,7 @@ public abstract class BotState implements PropertyManager {
} }
CachedBotState cachedState = turnContext.getTurnState().get(contextServiceKey); CachedBotState cachedState = turnContext.getTurnState().get(contextServiceKey);
if (force || (cachedState != null && cachedState.isChanged())) { if (force || cachedState != null && cachedState.isChanged()) {
String storageKey = getStorageKey(turnContext); String storageKey = getStorageKey(turnContext);
Map<String, Object> changes = new HashMap<String, Object>() {{ Map<String, Object> changes = new HashMap<String, Object>() {{
put(storageKey, cachedState.state); put(storageKey, cachedState.state);
@ -298,36 +299,43 @@ public abstract class BotState implements PropertyManager {
*/ */
private ObjectMapper mapper = new ObjectMapper(); private ObjectMapper mapper = new ObjectMapper();
public CachedBotState() { /**
* Construct with empty state.
*/
CachedBotState() {
this(null); this(null);
} }
public CachedBotState(Map<String, Object> withState) { /**
* Construct with supplied state.
* @param withState The initial state.
*/
CachedBotState(Map<String, Object> withState) {
state = withState != null ? withState : new ConcurrentHashMap<>(); state = withState != null ? withState : new ConcurrentHashMap<>();
hash = computeHash(withState); hash = computeHash(withState);
} }
public Map<String, Object> getState() { Map<String, Object> getState() {
return state; return state;
} }
public void setState(Map<String, Object> withState) { void setState(Map<String, Object> withState) {
state = withState; state = withState;
} }
public String getHash() { String getHash() {
return hash; return hash;
} }
public void setHash(String witHashCode) { void setHash(String witHashCode) {
hash = witHashCode; hash = witHashCode;
} }
public boolean isChanged() { boolean isChanged() {
return !StringUtils.equals(hash, computeHash(state)); return !StringUtils.equals(hash, computeHash(state));
} }
public String computeHash(Object obj) { String computeHash(Object obj) {
if (obj == null) { if (obj == null) {
return ""; return "";
} }
@ -345,8 +353,9 @@ public abstract class BotState implements PropertyManager {
* *
* <p>Note the semantic of this accessor are intended to be lazy, this means teh Get, Set and Delete * <p>Note the semantic of this accessor are intended to be lazy, this means teh Get, Set and Delete
* methods will first call LoadAsync. This will be a no-op if the data is already loaded. * methods will first call LoadAsync. This will be a no-op if the data is already loaded.
* The implication is you can just use this accessor in the application code directly without first calling LoadAsync * The implication is you can just use this accessor in the application code directly without first
* this approach works with the AutoSaveStateMiddleware which will save as needed at the end of a turn. * calling LoadAsync this approach works with the AutoSaveStateMiddleware which will save as needed
* at the end of a turn.</p>
* *
* @param <T> type of value the propertyAccessor accesses. * @param <T> type of value the propertyAccessor accesses.
*/ */

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

@ -59,8 +59,8 @@ public interface BotTelemetryClient {
* @param target External dependency target. * @param target External dependency target.
* @param dependencyName Name of the command initiated with this dependency call. Low cardinality value. * @param dependencyName Name of the command initiated with this dependency call. Low cardinality value.
* Examples are stored procedure name and URL path template. * Examples are stored procedure name and URL path template.
* @param data Command initiated by this dependency call. Examples are SQL statement and HTTP URL's with * @param data Command initiated by this dependency call. Examples are SQL statement and HTTP URL's
* all query parameters. * with all query parameters.
* @param startTime The time when the dependency was called. * @param startTime The time when the dependency was called.
* @param duration The time taken by the external dependency to handle the call. * @param duration The time taken by the external dependency to handle the call.
* @param resultCode Result code of dependency call execution. * @param resultCode Result code of dependency call execution.

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

@ -8,6 +8,9 @@ import com.microsoft.bot.schema.ConversationReference;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* A method that can participate in delete activity events for the current turn.
*/
@FunctionalInterface @FunctionalInterface
public interface DeleteActivityHandler { public interface DeleteActivityHandler {
/** /**

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

@ -159,7 +159,7 @@ public class RecognizerResult implements RecognizerConvert {
@Override @Override
public void convert(Object result) { public void convert(Object result) {
setText(((RecognizerResult) result).getText()); setText(((RecognizerResult) result).getText());
setAlteredText((((RecognizerResult) result).getAlteredText())); setAlteredText(((RecognizerResult) result).getAlteredText());
setIntents(((RecognizerResult) result).getIntents()); setIntents(((RecognizerResult) result).getIntents());
setEntities(((RecognizerResult) result).getEntities()); setEntities(((RecognizerResult) result).getEntities());

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

@ -5,7 +5,6 @@ package com.microsoft.bot.builder;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsoft.bot.connector.Channels; import com.microsoft.bot.connector.Channels;
import com.microsoft.bot.schema.Activity; import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes; import com.microsoft.bot.schema.ActivityTypes;

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

@ -6,7 +6,11 @@ package com.microsoft.bot.builder;
/** /**
* Telemetry logger property names. * Telemetry logger property names.
*/ */
public class TelemetryConstants { public final class TelemetryConstants {
private TelemetryConstants() {
}
public static final String CHANNELIDPROPERTY = "channelId"; public static final String CHANNELIDPROPERTY = "channelId";
public static final String CONVERSATIONIDPROPERTY = "conversationId"; public static final String CONVERSATIONIDPROPERTY = "conversationId";
public static final String CONVERSATIONNAMEPROPERTY = "conversationName"; public static final String CONVERSATIONNAMEPROPERTY = "conversationName";

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

@ -6,7 +6,11 @@ package com.microsoft.bot.builder;
/** /**
* The Telemetry Logger Event names. * The Telemetry Logger Event names.
*/ */
public class TelemetryLoggerConstants { public final class TelemetryLoggerConstants {
private TelemetryLoggerConstants() {
}
/** /**
* The name of the event when a new message is received from the user. * The name of the event when a new message is received from the user.
*/ */

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

@ -262,10 +262,8 @@ public class TelemetryLoggerMiddleware implements Middleware {
}}; }};
// Use the LogPersonalInformation flag to toggle logging PII data, text is a common example // Use the LogPersonalInformation flag to toggle logging PII data, text is a common example
if (logPersonalInformation) { if (logPersonalInformation && !StringUtils.isEmpty(activity.getText())) {
if (!StringUtils.isEmpty(activity.getText())) { properties.put(TelemetryConstants.TEXTPROPERTY, activity.getText());
properties.put(TelemetryConstants.TEXTPROPERTY, activity.getText());
}
} }
// Additional Properties can override "stock" properties. // Additional Properties can override "stock" properties.

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

@ -10,8 +10,6 @@ import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes; import com.microsoft.bot.schema.ActivityTypes;
import com.microsoft.bot.schema.ChannelAccount; import com.microsoft.bot.schema.ChannelAccount;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId; import java.time.ZoneId;
@ -24,8 +22,6 @@ import java.util.concurrent.ConcurrentLinkedQueue;
* When added, this middleware will log incoming and outgoing activities to a TranscriptStore. * When added, this middleware will log incoming and outgoing activities to a TranscriptStore.
*/ */
public class TranscriptLoggerMiddleware implements Middleware { public class TranscriptLoggerMiddleware implements Middleware {
private static final Logger logger = LoggerFactory.getLogger(TranscriptLoggerMiddleware.class);
/** /**
* To/From JSON. * To/From JSON.
*/ */

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

@ -474,7 +474,7 @@ public class TurnContextImpl implements TurnContext, AutoCloseable {
public void finalize() { public void finalize() {
try { try {
close(); close();
} catch (Exception e) { } catch (Exception ignored) {
} }
} }

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

@ -21,12 +21,10 @@ public class TurnContextStateCollection implements AutoCloseable {
Object service = state.get(key); Object service = state.get(key);
try { try {
T result = (T) service; return (T) service;
} catch (ClassCastException e) { } catch (ClassCastException e) {
return null; return null;
} }
return (T) service;
} }
/** /**
@ -98,7 +96,7 @@ public class TurnContextStateCollection implements AutoCloseable {
public void finalize() { public void finalize() {
try { try {
close(); close();
} catch (Exception e) { } catch (Exception ignored) {
} }
} }

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

@ -6,6 +6,7 @@ package com.microsoft.bot.builder;
import com.microsoft.bot.schema.TokenResponse; import com.microsoft.bot.schema.TokenResponse;
import com.microsoft.bot.schema.TokenStatus; import com.microsoft.bot.schema.TokenStatus;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -74,7 +75,7 @@ public interface UserTokenProvider {
* @param userId The user Id for which token status is retrieved. * @param userId The user Id for which token status is retrieved.
* @return Array of TokenStatus. * @return Array of TokenStatus.
*/ */
default CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext turnContext, String userId) { default CompletableFuture<List<TokenStatus>> getTokenStatus(TurnContext turnContext, String userId) {
return getTokenStatus(turnContext, userId, null); return getTokenStatus(turnContext, userId, null);
} }
@ -87,7 +88,7 @@ public interface UserTokenProvider {
* for all configured connections. * for all configured connections.
* @return Array of TokenStatus. * @return Array of TokenStatus.
*/ */
CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext turnContext, String userId, String includeFilter); CompletableFuture<List<TokenStatus>> getTokenStatus(TurnContext turnContext, String userId, String includeFilter);
/** /**
* Retrieves Azure Active Directory tokens for particular resources on a configured connection. * Retrieves Azure Active Directory tokens for particular resources on a configured connection.

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

@ -7,28 +7,48 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.microsoft.bot.schema.Activity; import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ConversationReference; import com.microsoft.bot.schema.ConversationReference;
public final class InspectionActivityExtensions { final class InspectionActivityExtensions {
private InspectionActivityExtensions() { private InspectionActivityExtensions() {
} }
public static Activity makeCommandActivity(String command) { static Activity makeCommandActivity(String command) {
return Activity.createTraceActivity("Command", "https://www.botframework.com/schemas/command", command, "Command"); return Activity.createTraceActivity(
"Command",
"https://www.botframework.com/schemas/command",
command,
"Command");
} }
public static Activity traceActivity(JsonNode state) { static Activity traceActivity(JsonNode state) {
return Activity.createTraceActivity("BotState", "https://www.botframework.com/schemas/botState", state, "Bot State"); return Activity.createTraceActivity(
"BotState",
"https://www.botframework.com/schemas/botState",
state,
"Bot State");
} }
public static Activity traceActivity(Activity activity, String name, String label) { static Activity traceActivity(Activity activity, String name, String label) {
return Activity.createTraceActivity(name, "https://www.botframework.com/schemas/activity", activity, label); return Activity.createTraceActivity(
name,
"https://www.botframework.com/schemas/activity",
activity,
label);
} }
public static Activity traceActivity(ConversationReference conversationReference) { static Activity traceActivity(ConversationReference conversationReference) {
return Activity.createTraceActivity("MessageDelete", "https://www.botframework.com/schemas/conversationReference", conversationReference, "Deleted Message"); return Activity.createTraceActivity(
"MessageDelete",
"https://www.botframework.com/schemas/conversationReference",
conversationReference,
"Deleted Message");
} }
public static Activity traceActivity(Throwable exception) { static Activity traceActivity(Throwable exception) {
return Activity.createTraceActivity("TurnError", "https://www.botframework.com/schemas/error", exception.getMessage(), "Turn Error"); return Activity.createTraceActivity(
"TurnError",
"https://www.botframework.com/schemas/error",
exception.getMessage(),
"Turn Error");
} }
} }

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

@ -5,7 +5,11 @@ package com.microsoft.bot.builder.inspection;
import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsoft.bot.builder.*; import com.microsoft.bot.builder.ConversationState;
import com.microsoft.bot.builder.MessageFactory;
import com.microsoft.bot.builder.StatePropertyAccessor;
import com.microsoft.bot.builder.TurnContext;
import com.microsoft.bot.builder.UserState;
import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials; import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials;
import com.microsoft.bot.schema.Activity; import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes; import com.microsoft.bot.schema.ActivityTypes;

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

@ -18,14 +18,16 @@ import java.util.stream.Collectors;
public abstract class InterceptionMiddleware implements Middleware { public abstract class InterceptionMiddleware implements Middleware {
private Logger logger; private Logger logger;
public static class Intercept { static class Intercept {
public Intercept(boolean forward, boolean intercept) { Intercept(boolean forward, boolean intercept) {
shouldForwardToApplication = forward; shouldForwardToApplication = forward;
shouldIntercept = intercept; shouldIntercept = intercept;
} }
public boolean shouldForwardToApplication; @SuppressWarnings({"checkstyle:JavadocVariable", "checkstyle:VisibilityModifier"})
public boolean shouldIntercept; boolean shouldForwardToApplication;
@SuppressWarnings({"checkstyle:JavadocVariable", "checkstyle:VisibilityModifier"})
boolean shouldIntercept;
} }
public InterceptionMiddleware(Logger withLogger) { public InterceptionMiddleware(Logger withLogger) {
@ -125,7 +127,7 @@ public abstract class InterceptionMiddleware implements Middleware {
} }
private CompletableFuture<Void> invokeTraceException(TurnContext turnContext, Activity traceActivity) { private CompletableFuture<Void> invokeTraceException(TurnContext turnContext, Activity traceActivity) {
return outbound(turnContext, Collections.singletonList(Activity.createContactRelationUpdateActivity())) return outbound(turnContext, Collections.singletonList(traceActivity))
.exceptionally(exception -> { .exceptionally(exception -> {
logger.warn("Exception in exception interception {}", exception.getMessage()); logger.warn("Exception in exception interception {}", exception.getMessage());
return null; return null;

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

@ -47,8 +47,8 @@ public interface UserToken {
* @return the observable to the Map&lt;String, TokenResponse&gt; object * @return the observable to the Map&lt;String, TokenResponse&gt; object
*/ */
CompletableFuture<Map<String, TokenResponse>> getAadTokens(String userId, CompletableFuture<Map<String, TokenResponse>> getAadTokens(String userId,
String connectionName, String connectionName,
AadResourceUrls aadResourceUrls); AadResourceUrls aadResourceUrls);
/** /**
* *

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

@ -6,6 +6,7 @@
package com.microsoft.bot.schema; package com.microsoft.bot.schema;
import java.util.Arrays;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
@ -19,24 +20,37 @@ public class AadResourceUrls {
@JsonProperty(value = "resourceUrls") @JsonProperty(value = "resourceUrls")
private List<String> resourceUrls; private List<String> resourceUrls;
/**
* Construct with var args or String[].
* @param withResourceUrl Array of urls.
*/
public AadResourceUrls(String... withResourceUrl) {
resourceUrls = Arrays.asList(withResourceUrl);
}
/**
* Construct with List of urls.
* @param withResourceUrls List of urls.
*/
public AadResourceUrls(List<String> withResourceUrls) {
resourceUrls = withResourceUrls;
}
/** /**
* Get the resourceUrls value. * Get the resourceUrls value.
* *
* @return the resourceUrls value * @return the resourceUrls value
*/ */
public List<String> resourceUrls() { public List<String> getResourceUrls() {
return this.resourceUrls; return resourceUrls;
} }
/** /**
* Set the resourceUrls value. * Set the resourceUrls value.
* *
* @param resourceUrls the resourceUrls value to set * @param withResourceUrls the resourceUrls value to set
* @return the AadResourceUrls object itself.
*/ */
public AadResourceUrls withResourceUrls(List<String> resourceUrls) { public void setResourceUrls(List<String> withResourceUrls) {
this.resourceUrls = resourceUrls; resourceUrls = withResourceUrls;
return this;
} }
} }