Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SyncStack-TextAnlytics] Add SyncStack support in TA #32867

Merged
merged 11 commits into from
Jan 26, 2023
1 change: 1 addition & 0 deletions sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 5.3.0-beta.2 (Unreleased)

### Features Added
- Integrate synchronous workflow for sync clients so that they do not block on async client APIs.
mssfang marked this conversation as resolved.
Show resolved Hide resolved

### Breaking Changes

Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl;
import com.azure.ai.textanalytics.implementation.Utility;
import com.azure.ai.textanalytics.implementation.models.AnalyzeTextSentimentAnalysisInput;
import com.azure.ai.textanalytics.implementation.models.ErrorResponseException;
import com.azure.ai.textanalytics.implementation.models.MultiLanguageAnalysisInput;
import com.azure.ai.textanalytics.implementation.models.MultiLanguageBatchInput;
import com.azure.ai.textanalytics.implementation.models.SentimentAnalysisTaskParameters;
Expand All @@ -15,6 +16,7 @@
import com.azure.ai.textanalytics.models.AnalyzeSentimentOptions;
import com.azure.ai.textanalytics.models.TextDocumentInput;
import com.azure.ai.textanalytics.util.AnalyzeSentimentResultCollection;
import com.azure.core.exception.HttpResponseException;
import com.azure.core.http.rest.Response;
import com.azure.core.http.rest.SimpleResponse;
import com.azure.core.util.Context;
Expand All @@ -24,11 +26,15 @@
import java.util.Arrays;

import static com.azure.ai.textanalytics.TextAnalyticsAsyncClient.COGNITIVE_TRACING_NAMESPACE_VALUE;
import static com.azure.ai.textanalytics.implementation.Utility.HTTP_REST_PROXY_SYNC_PROXY_ENABLE;
import static com.azure.ai.textanalytics.implementation.Utility.getDocumentCount;
import static com.azure.ai.textanalytics.implementation.Utility.getNotNullContext;
import static com.azure.ai.textanalytics.implementation.Utility.getUnsupportedServiceApiVersionMessage;
import static com.azure.ai.textanalytics.implementation.Utility.inputDocumentsValidation;
import static com.azure.ai.textanalytics.implementation.Utility.mapToHttpResponseExceptionIfExists;
import static com.azure.ai.textanalytics.implementation.Utility.throwIfTargetServiceVersionFound;
import static com.azure.ai.textanalytics.implementation.Utility.toAnalyzeSentimentResultCollectionResponseLanguageApi;
import static com.azure.ai.textanalytics.implementation.Utility.toAnalyzeSentimentResultCollectionResponseLegacyApi;
import static com.azure.ai.textanalytics.implementation.Utility.toMultiLanguageInput;
import static com.azure.core.util.FluxUtil.monoError;
import static com.azure.core.util.FluxUtil.withContext;
Expand All @@ -37,20 +43,20 @@
/**
* Helper class for managing sentiment analysis endpoint.
*/
class AnalyzeSentimentAsyncClient {
private final ClientLogger logger = new ClientLogger(AnalyzeSentimentAsyncClient.class);
class AnalyzeSentimentUtilClient {
private static final ClientLogger LOGGER = new ClientLogger(AnalyzeSentimentUtilClient.class);
private final TextAnalyticsClientImpl legacyService;
private final MicrosoftCognitiveLanguageServiceTextAnalysisImpl service;

private final TextAnalyticsServiceVersion serviceVersion;

AnalyzeSentimentAsyncClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
AnalyzeSentimentUtilClient(TextAnalyticsClientImpl legacyService, TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = legacyService;
this.service = null;
this.serviceVersion = serviceVersion;
}

AnalyzeSentimentAsyncClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
AnalyzeSentimentUtilClient(MicrosoftCognitiveLanguageServiceTextAnalysisImpl service,
TextAnalyticsServiceVersion serviceVersion) {
this.legacyService = null;
this.service = service;
Expand All @@ -75,27 +81,7 @@ public Mono<Response<AnalyzeSentimentResultCollection>> analyzeSentimentBatch(
try {
return withContext(context -> getAnalyzedSentimentResponse(documents, options, context));
} catch (RuntimeException ex) {
return monoError(logger, ex);
}
}

/**
* Helper function for calling service with max overloaded parameters that returns a mono {@link Response}
* which contains {@link AnalyzeSentimentResultCollection}.
*
* @param documents The list of documents to analyze sentiments for.
* @param options The additional configurable {@link AnalyzeSentimentOptions options} that may be passed when
* analyzing sentiments.
* @param context Additional context that is passed through the Http pipeline during the service call.
*
* @return A mono {@link Response} contains {@link AnalyzeSentimentResultCollection}.
*/
Mono<Response<AnalyzeSentimentResultCollection>> analyzeSentimentBatchWithContext(
Iterable<TextDocumentInput> documents, AnalyzeSentimentOptions options, Context context) {
try {
return getAnalyzedSentimentResponse(documents, options, context);
} catch (RuntimeException ex) {
return monoError(logger, ex);
return monoError(LOGGER, ex);
}
}

Expand All @@ -117,27 +103,25 @@ private Mono<Response<AnalyzeSentimentResultCollection>> getAnalyzedSentimentRes
options = options == null ? new AnalyzeSentimentOptions() : options;

if (service != null) {
return service
.analyzeTextWithResponseAsync(
new AnalyzeTextSentimentAnalysisInput()
.setParameters(
new SentimentAnalysisTaskParameters()
.setStringIndexType(StringIndexType.UTF16CODE_UNIT)
.setOpinionMining(options.isIncludeOpinionMining())
.setModelVersion(options.getModelVersion())
.setLoggingOptOut(options.isServiceLogsDisabled()))
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents))),
options.isIncludeStatistics(),
getNotNullContext(context)
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE))
.doOnSubscribe(ignoredValue -> logger.info("A batch of documents with count - {}",
getDocumentCount(documents)))
.doOnSuccess(response -> logger.info("Analyzed sentiment for a batch of documents - {}",
response))
.doOnError(error -> logger.warning("Failed to analyze sentiment - {}", error))
.map(Utility::toAnalyzeSentimentResultCollectionResponseLanguageApi)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
return service.analyzeTextWithResponseAsync(
new AnalyzeTextSentimentAnalysisInput()
.setParameters(
new SentimentAnalysisTaskParameters()
.setStringIndexType(StringIndexType.UTF16CODE_UNIT)
.setOpinionMining(options.isIncludeOpinionMining())
.setModelVersion(options.getModelVersion())
.setLoggingOptOut(options.isServiceLogsDisabled()))
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents))),
options.isIncludeStatistics(),
getNotNullContext(context).addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE))
.doOnSubscribe(ignoredValue -> LOGGER.info("A batch of documents with count - {}",
getDocumentCount(documents)))
.doOnSuccess(response -> LOGGER.info("Analyzed sentiment for a batch of documents - {}",
response))
.doOnError(error -> LOGGER.warning("Failed to analyze sentiment - {}", error))
.map(Utility::toAnalyzeSentimentResultCollectionResponseLanguageApi)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
}

return legacyService.sentimentWithResponseAsync(
Expand All @@ -148,14 +132,60 @@ private Mono<Response<AnalyzeSentimentResultCollection>> getAnalyzedSentimentRes
options.isIncludeOpinionMining(),
StringIndexType.UTF16CODE_UNIT,
getNotNullContext(context).addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE))
.doOnSubscribe(ignoredValue -> logger.info("A batch of documents with count - {}",
.doOnSubscribe(ignoredValue -> LOGGER.info("A batch of documents with count - {}",
getDocumentCount(documents)))
.doOnSuccess(response -> logger.info("Analyzed sentiment for a batch of documents - {}", response))
.doOnError(error -> logger.warning("Failed to analyze sentiment - {}", error))
.doOnSuccess(response -> LOGGER.info("Analyzed sentiment for a batch of documents - {}", response))
.doOnError(error -> LOGGER.warning("Failed to analyze sentiment - {}", error))
.map(Utility::toAnalyzeSentimentResultCollectionResponseLegacyApi)
.onErrorMap(Utility::mapToHttpResponseExceptionIfExists);
}

/**
* Call the service with REST response, convert to a {@link Mono} of {@link Response} which contains
* {@link AnalyzeSentimentResultCollection} from a {@link SimpleResponse} of {@link SentimentResponse}.
*
* @param documents A list of documents to be analyzed.
* @param options The additional configurable {@link AnalyzeSentimentOptions options} that may be passed when
* analyzing sentiments.
* @param context Additional context that is passed through the Http pipeline during the service call.
*
* @return A {@link Response} contains {@link AnalyzeSentimentResultCollection}.
*/
Response<AnalyzeSentimentResultCollection> getAnalyzedSentimentResponseSync(
Iterable<TextDocumentInput> documents, AnalyzeSentimentOptions options, Context context) {
throwIfCallingNotAvailableFeatureInOptions(options);
inputDocumentsValidation(documents);
options = options == null ? new AnalyzeSentimentOptions() : options;
context = enableSyncRestProxy(getNotNullContext(context))
.addData(AZ_TRACING_NAMESPACE_KEY, COGNITIVE_TRACING_NAMESPACE_VALUE);

try {
return (service != null)
? toAnalyzeSentimentResultCollectionResponseLanguageApi(service.analyzeTextWithResponse(
new AnalyzeTextSentimentAnalysisInput()
.setParameters(
new SentimentAnalysisTaskParameters()
.setStringIndexType(StringIndexType.UTF16CODE_UNIT)
.setOpinionMining(options.isIncludeOpinionMining())
.setModelVersion(options.getModelVersion())
.setLoggingOptOut(options.isServiceLogsDisabled()))
.setAnalysisInput(
new MultiLanguageAnalysisInput().setDocuments(toMultiLanguageInput(documents))),
options.isIncludeStatistics(),
context))
: toAnalyzeSentimentResultCollectionResponseLegacyApi(legacyService.sentimentWithResponseSync(
new MultiLanguageBatchInput().setDocuments(toMultiLanguageInput(documents)),
options.getModelVersion(),
options.isIncludeStatistics(),
options.isServiceLogsDisabled(),
options.isIncludeOpinionMining(),
StringIndexType.UTF16CODE_UNIT,
context));
} catch (ErrorResponseException ex) {
throw LOGGER.logExceptionAsError((HttpResponseException) mapToHttpResponseExceptionIfExists(ex));
}
}

private void throwIfCallingNotAvailableFeatureInOptions(AnalyzeSentimentOptions options) {
if (options == null) {
return;
Expand All @@ -171,4 +201,8 @@ private void throwIfCallingNotAvailableFeatureInOptions(AnalyzeSentimentOptions
serviceVersion, TextAnalyticsServiceVersion.V3_1));
}
}

private Context enableSyncRestProxy(Context context) {
return context.addData(HTTP_REST_PROXY_SYNC_PROXY_ENABLE, true);
}
}
Loading