diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java new file mode 100644 index 000000000000..6c3afcff0eaf --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/AnalyzeSentimentAsyncClient.java @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics; + +import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl; +import com.azure.ai.textanalytics.implementation.models.DocumentError; +import com.azure.ai.textanalytics.implementation.models.DocumentSentiment; +import com.azure.ai.textanalytics.implementation.models.MultiLanguageBatchInput; +import com.azure.ai.textanalytics.implementation.models.SentimentConfidenceScorePerLabel; +import com.azure.ai.textanalytics.implementation.models.SentimentResponse; +import com.azure.ai.textanalytics.models.AnalyzeSentimentResult; +import com.azure.ai.textanalytics.models.DocumentResultCollection; +import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; +import com.azure.ai.textanalytics.models.TextDocumentInput; +import com.azure.ai.textanalytics.models.TextSentiment; +import com.azure.ai.textanalytics.models.TextSentimentClass; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.azure.ai.textanalytics.Transforms.mapByIndex; +import static com.azure.ai.textanalytics.Transforms.toBatchStatistics; +import static com.azure.ai.textanalytics.Transforms.toMultiLanguageInput; +import static com.azure.ai.textanalytics.Transforms.toTextAnalyticsError; +import static com.azure.ai.textanalytics.Transforms.toTextDocumentStatistics; + +/** + * Helper class for managing sentiment analysis endpoint. + */ +class AnalyzeSentimentAsyncClient { + private final ClientLogger logger = new ClientLogger(AnalyzeSentimentAsyncClient.class); + private final TextAnalyticsClientImpl service; + + /** + * Create a {@code AnalyzeSentimentAsyncClient} that sends requests to the Text Analytics services's sentiment + * analysis endpoint. + * + * @param service The proxy service used to perform REST calls. + */ + AnalyzeSentimentAsyncClient(TextAnalyticsClientImpl service) { + this.service = service; + } + + Mono> analyzeSentimentWithResponse(String text, String language, Context context) { + Objects.requireNonNull(text, "'text' cannot be null."); + + return analyzeBatchSentimentWithResponse( + Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) + .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + } + + Mono>> analyzeSentimentWithResponse( + List textInputs, String language, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + List documentInputs = mapByIndex(textInputs, (index, value) -> + new TextDocumentInput(index, value, language)); + return analyzeBatchSentimentWithResponse(documentInputs, null, context); + } + + Mono>> analyzeBatchSentimentWithResponse( + List textInputs, TextAnalyticsRequestOptions options, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() + .setDocuments(toMultiLanguageInput(textInputs)); + return service.sentimentWithRestResponseAsync( + batchInput, + options == null ? null : options.getModelVersion(), + options == null ? null : options.showStatistics(), context) + .doOnSubscribe(ignoredValue -> logger.info("A batch of text sentiment input - {}", textInputs.toString())) + .doOnSuccess(response -> logger.info("A batch of text sentiment output - {}", response)) + .doOnError(error -> logger.warning("Failed to analyze text sentiment - {}", error)) + .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); + } + + /** + * Helper method to convert the service response of {@link SentimentResponse} to {@link DocumentResultCollection}. + * + * @param sentimentResponse the {@link SentimentResponse} returned by the service. + * + * @return the {@link DocumentResultCollection} of {@link AnalyzeSentimentResult} to be returned by the SDK. + */ + private DocumentResultCollection toDocumentResultCollection( + final SentimentResponse sentimentResponse) { + List analyzeSentimentResults = new ArrayList<>(); + for (DocumentSentiment documentSentiment : sentimentResponse.getDocuments()) { + analyzeSentimentResults.add(convertToTextSentimentResult(documentSentiment)); + } + for (DocumentError documentError : sentimentResponse.getErrors()) { + final com.azure.ai.textanalytics.models.TextAnalyticsError error = + toTextAnalyticsError(documentError.getError()); + analyzeSentimentResults.add(new AnalyzeSentimentResult(documentError.getId(), null, + error, null, null)); + } + return new DocumentResultCollection<>(analyzeSentimentResults, + sentimentResponse.getModelVersion(), sentimentResponse.getStatistics() == null ? null + : toBatchStatistics(sentimentResponse.getStatistics())); + } + + /** + * Helper method to convert the service response of {@link DocumentSentiment} to {@link AnalyzeSentimentResult}. + * + * @param documentSentiment the {@link DocumentSentiment} returned by the service. + * + * @return the {@link AnalyzeSentimentResult} to be returned by the SDK. + */ + private AnalyzeSentimentResult convertToTextSentimentResult(final DocumentSentiment documentSentiment) { + // Document text sentiment + final TextSentimentClass documentSentimentClass = TextSentimentClass.fromString(documentSentiment. + getSentiment().toString()); + if (documentSentimentClass == null) { + // Not throw exception for an invalid Sentiment type because we should not skip processing the + // other response. It is a service issue. + logger.logExceptionAsWarning( + new RuntimeException(String.format("'%s' is not valid text sentiment.", + documentSentiment.getSentiment()))); + } + final SentimentConfidenceScorePerLabel confidenceScorePerLabel = documentSentiment.getDocumentScores(); + + // Sentence text sentiment + final List sentenceSentimentTexts = documentSentiment.getSentences().stream() + .map(sentenceSentiment -> { + TextSentimentClass sentimentClass = TextSentimentClass.fromString(sentenceSentiment + .getSentiment().toString()); + if (sentimentClass == null) { + // Not throw exception for an invalid Sentiment type because we should not skip processing the + // other response. It is a service issue. + logger.logExceptionAsWarning( + new RuntimeException(String.format("'%s' is not valid text sentiment.", + sentenceSentiment.getSentiment()))); + } + SentimentConfidenceScorePerLabel confidenceScorePerSentence = sentenceSentiment.getSentenceScores(); + + return new TextSentiment(sentimentClass, confidenceScorePerSentence.getNegative(), + confidenceScorePerSentence.getNeutral(), confidenceScorePerSentence.getPositive(), + sentenceSentiment.getLength(), sentenceSentiment.getOffset()); + + }).collect(Collectors.toList()); + + return new AnalyzeSentimentResult(documentSentiment.getId(), + documentSentiment.getStatistics() == null ? null + : toTextDocumentStatistics(documentSentiment.getStatistics()), null, + new TextSentiment(documentSentimentClass, confidenceScorePerLabel.getNegative(), + confidenceScorePerLabel.getNeutral(), confidenceScorePerLabel.getPositive(), + sentenceSentimentTexts.stream().mapToInt(TextSentiment::getLength).sum(), 0), + sentenceSentimentTexts); + } + +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java new file mode 100644 index 000000000000..af2ab897ac65 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/DetectLanguageAsyncClient.java @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics; + +import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl; +import com.azure.ai.textanalytics.implementation.models.DocumentError; +import com.azure.ai.textanalytics.implementation.models.DocumentLanguage; +import com.azure.ai.textanalytics.implementation.models.LanguageBatchInput; +import com.azure.ai.textanalytics.implementation.models.LanguageInput; +import com.azure.ai.textanalytics.implementation.models.LanguageResult; +import com.azure.ai.textanalytics.models.DetectLanguageInput; +import com.azure.ai.textanalytics.models.DetectLanguageResult; +import com.azure.ai.textanalytics.models.DetectedLanguage; +import com.azure.ai.textanalytics.models.DocumentResultCollection; +import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.azure.ai.textanalytics.Transforms.mapByIndex; + +/** + * Helper class for managing detect language endpoint. + */ +class DetectLanguageAsyncClient { + private final ClientLogger logger = new ClientLogger(DetectLanguageAsyncClient.class); + private final TextAnalyticsClientImpl service; + + /** + * Create a {@code DetectLanguageAsyncClient} that sends requests to the Text Analytics services's detect language + * endpoint. + * + * @param service The proxy service used to perform REST calls. + */ + DetectLanguageAsyncClient(TextAnalyticsClientImpl service) { + this.service = service; + } + + Mono> detectLanguageWithResponse(String text, String countryHint, Context context) { + Objects.requireNonNull(text, "'text' cannot be null."); + List languageInputs = Collections.singletonList(new DetectLanguageInput("0", + text, countryHint)); + return detectBatchLanguagesWithResponse(languageInputs, null, context).map(response -> + new SimpleResponse<>(response, response.getValue().iterator().next())); + } + + Mono>> detectLanguagesWithResponse(List textInputs, + String countryHint, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + List detectLanguageInputs = mapByIndex(textInputs, (index, value) -> + new DetectLanguageInput(index, value, countryHint)); + + return detectBatchLanguagesWithResponse(detectLanguageInputs, null, context); + } + + Mono>> detectBatchLanguagesWithResponse( + List textInputs, TextAnalyticsRequestOptions options, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + final LanguageBatchInput languageBatchInput = new LanguageBatchInput() + .setDocuments(textInputs.stream().map(detectLanguageInput -> new LanguageInput() + .setId(detectLanguageInput.getId()).setText(detectLanguageInput.getText()) + .setCountryHint(detectLanguageInput.getCountryHint())).collect(Collectors.toList())); + + return service.languagesWithRestResponseAsync( + languageBatchInput, options == null ? null : options.getModelVersion(), + options == null ? null : options.showStatistics(), context) + .doOnSubscribe(ignoredValue -> logger.info("A batch of language input - {}", textInputs.toString())) + .doOnSuccess(response -> logger.info("A batch of detected language output - {}", response.getValue())) + .doOnError(error -> logger.warning("Failed to detect languages - {}", error)) + .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); + } + + /** + * Helper method to convert the service response of {@link LanguageResult} to {@link DocumentResultCollection}. + * + * @param languageResult the {@link LanguageResult} returned by the service. + * + * @return the {@link DocumentResultCollection} of {@link DetectLanguageResult} to be returned by the SDK. + */ + private DocumentResultCollection toDocumentResultCollection( + final LanguageResult languageResult) { + + final List detectLanguageResults = new ArrayList<>(); + for (DocumentLanguage documentLanguage : languageResult.getDocuments()) { + DetectedLanguage primaryLanguage = null; + if (documentLanguage.getDetectedLanguages().size() >= 1) { + com.azure.ai.textanalytics.implementation.models.DetectedLanguage detectedLanguageResult = + documentLanguage.getDetectedLanguages().get(0); + primaryLanguage = new DetectedLanguage(detectedLanguageResult.getName(), + detectedLanguageResult.getIso6391Name(), detectedLanguageResult.getScore()); + } + detectLanguageResults.add(new DetectLanguageResult(documentLanguage.getId(), + documentLanguage.getStatistics() == null + ? null : Transforms.toTextDocumentStatistics(documentLanguage.getStatistics()), + null, + primaryLanguage, + documentLanguage.getDetectedLanguages().stream().map(detectedLanguage -> + new DetectedLanguage(detectedLanguage.getName(), detectedLanguage.getIso6391Name(), + detectedLanguage.getScore())).collect(Collectors.toList()))); + } + + for (DocumentError documentError : languageResult.getErrors()) { + com.azure.ai.textanalytics.models.TextAnalyticsError error = + Transforms.toTextAnalyticsError(documentError.getError()); + detectLanguageResults.add( + new DetectLanguageResult(documentError.getId(), null, error, null, null)); + } + + return new DocumentResultCollection<>(detectLanguageResults, languageResult.getModelVersion(), + languageResult.getStatistics() == null ? null + : Transforms.toBatchStatistics(languageResult.getStatistics())); + } + +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java new file mode 100644 index 000000000000..05c76b9d2716 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/ExtractKeyPhraseAsyncClient.java @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics; + +import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl; +import com.azure.ai.textanalytics.implementation.models.DocumentError; +import com.azure.ai.textanalytics.implementation.models.DocumentKeyPhrases; +import com.azure.ai.textanalytics.implementation.models.KeyPhraseResult; +import com.azure.ai.textanalytics.implementation.models.MultiLanguageBatchInput; +import com.azure.ai.textanalytics.models.DocumentResultCollection; +import com.azure.ai.textanalytics.models.ExtractKeyPhraseResult; +import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; +import com.azure.ai.textanalytics.models.TextDocumentInput; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static com.azure.ai.textanalytics.Transforms.mapByIndex; +import static com.azure.ai.textanalytics.Transforms.toBatchStatistics; +import static com.azure.ai.textanalytics.Transforms.toMultiLanguageInput; +import static com.azure.ai.textanalytics.Transforms.toTextAnalyticsError; +import static com.azure.ai.textanalytics.Transforms.toTextDocumentStatistics; + +/** + * Helper class for managing extract keyphrase endpoint. + */ +class ExtractKeyPhraseAsyncClient { + private final ClientLogger logger = new ClientLogger(ExtractKeyPhraseAsyncClient.class); + private final TextAnalyticsClientImpl service; + + /** + * Create a {@code ExtractKeyPhraseAsyncClient} that sends requests to the Text Analytics services's extract + * keyphrase endpoint. + * + * @param service The proxy service used to perform REST calls. + */ + ExtractKeyPhraseAsyncClient(TextAnalyticsClientImpl service) { + this.service = service; + } + + Mono> extractKeyPhrasesWithResponse(String text, String language, + Context context) { + Objects.requireNonNull(text, "'text' cannot be null."); + + return extractBatchKeyPhrasesWithResponse( + Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) + .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + } + + Mono>> extractKeyPhrasesWithResponse( + List textInputs, String language, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + List documentInputs = mapByIndex(textInputs, (index, value) -> + new TextDocumentInput(index, value, language)); + return extractBatchKeyPhrasesWithResponse(documentInputs, null, context); + } + + Mono>> extractBatchKeyPhrasesWithResponse( + List textInputs, TextAnalyticsRequestOptions options, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() + .setDocuments(toMultiLanguageInput(textInputs)); + return service.keyPhrasesWithRestResponseAsync( + batchInput, + options == null ? null : options.getModelVersion(), + options == null ? null : options.showStatistics(), context) + .doOnSubscribe(ignoredValue -> logger.info("A batch of key phrases input - {}", textInputs.toString())) + .doOnSuccess(response -> logger.info("A batch of key phrases output - {}", response.getValue())) + .doOnError(error -> logger.warning("Failed to extract key phrases - {}", error)) + .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); + } + + /** + * Helper method to convert the service response of {@link KeyPhraseResult} to {@link DocumentResultCollection}. + * + * @param keyPhraseResult the {@link KeyPhraseResult} returned by the service. + * + * @return the {@link DocumentResultCollection} of {@link KeyPhraseResult} to be returned by the SDK. + */ + private DocumentResultCollection toDocumentResultCollection( + final KeyPhraseResult keyPhraseResult) { + List keyPhraseResultList = new ArrayList<>(); + for (DocumentKeyPhrases documentKeyPhrases : keyPhraseResult.getDocuments()) { + keyPhraseResultList.add(new ExtractKeyPhraseResult(documentKeyPhrases.getId(), + documentKeyPhrases.getStatistics() == null ? null + : toTextDocumentStatistics(documentKeyPhrases.getStatistics()), null, + documentKeyPhrases.getKeyPhrases())); + } + + for (DocumentError documentError : keyPhraseResult.getErrors()) { + final com.azure.ai.textanalytics.models.TextAnalyticsError error = + toTextAnalyticsError(documentError.getError()); + keyPhraseResultList.add(new ExtractKeyPhraseResult(documentError.getId(), null, error, null)); + } + + return new DocumentResultCollection<>(keyPhraseResultList, + keyPhraseResult.getModelVersion(), keyPhraseResult.getStatistics() == null ? null + : toBatchStatistics(keyPhraseResult.getStatistics())); + } +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java new file mode 100644 index 000000000000..9a12fcfb3661 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeEntityAsyncClient.java @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics; + +import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl; +import com.azure.ai.textanalytics.implementation.models.DocumentEntities; +import com.azure.ai.textanalytics.implementation.models.DocumentError; +import com.azure.ai.textanalytics.implementation.models.EntitiesResult; +import com.azure.ai.textanalytics.implementation.models.MultiLanguageBatchInput; +import com.azure.ai.textanalytics.models.DetectLanguageResult; +import com.azure.ai.textanalytics.models.DocumentResultCollection; +import com.azure.ai.textanalytics.models.NamedEntity; +import com.azure.ai.textanalytics.models.RecognizeEntitiesResult; +import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; +import com.azure.ai.textanalytics.models.TextDocumentInput; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.azure.ai.textanalytics.Transforms.toTextAnalyticsError; +import static com.azure.ai.textanalytics.Transforms.toTextDocumentStatistics; +import static com.azure.ai.textanalytics.Transforms.toBatchStatistics; +import static com.azure.ai.textanalytics.Transforms.mapByIndex; + +/** + * Helper class for managing recognize entity endpoint. + */ +class RecognizeEntityAsyncClient { + private final ClientLogger logger = new ClientLogger(RecognizeEntityAsyncClient.class); + private final TextAnalyticsClientImpl service; + + /** + * Create a {@code RecognizeEntityAsyncClient} that sends requests to the Text Analytics services's recognize entity + * endpoint. + * + * @param service The proxy service used to perform REST calls. + */ + RecognizeEntityAsyncClient(TextAnalyticsClientImpl service) { + this.service = service; + } + + Mono> recognizeEntitiesWithResponse(String text, String language, + Context context) { + Objects.requireNonNull(text, "'text' cannot be null."); + + return recognizeBatchEntitiesWithResponse( + Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) + .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + } + + Mono>> recognizeEntitiesWithResponse( + List textInputs, String language, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + List documentInputs = mapByIndex(textInputs, (index, value) -> + new TextDocumentInput(index, value, language)); + return recognizeBatchEntitiesWithResponse(documentInputs, null, context); + } + + Mono>> recognizeBatchEntitiesWithResponse( + List textInputs, TextAnalyticsRequestOptions options, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() + .setDocuments(Transforms.toMultiLanguageInput(textInputs)); + return service.entitiesRecognitionGeneralWithRestResponseAsync( + batchInput, + options == null ? null : options.getModelVersion(), + options == null ? null : options.showStatistics(), context) + .doOnSubscribe(ignoredValue -> logger.info("A batch of named entities input - {}", textInputs.toString())) + .doOnSuccess(response -> logger.info("A batch of named entities output - {}", response.getValue())) + .doOnError(error -> logger.warning("Failed to recognize named entities - {}", error)) + .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); + } + + /** + * Helper method to convert the service response of {@link EntitiesResult} to {@link DocumentResultCollection}. + * + * @param entitiesResult the {@link EntitiesResult} returned by the service. + * + * @return the {@link DocumentResultCollection} of {@link DetectLanguageResult} to be returned by the SDK. + */ + private DocumentResultCollection toDocumentResultCollection( + final EntitiesResult entitiesResult) { + List recognizeEntitiesResults = new ArrayList<>(); + for (DocumentEntities documentEntities : entitiesResult.getDocuments()) { + recognizeEntitiesResults.add(new RecognizeEntitiesResult(documentEntities.getId(), + documentEntities.getStatistics() == null ? null + : toTextDocumentStatistics(documentEntities.getStatistics()), + null, documentEntities.getEntities().stream().map(entity -> + new NamedEntity(entity.getText(), entity.getType(), entity.getSubtype(), entity.getOffset(), + entity.getLength(), entity.getScore())).collect(Collectors.toList()))); + } + + for (DocumentError documentError : entitiesResult.getErrors()) { + final com.azure.ai.textanalytics.models.TextAnalyticsError error = + toTextAnalyticsError(documentError.getError()); + recognizeEntitiesResults.add(new RecognizeEntitiesResult(documentError.getId(), null, error, null)); + } + + return new DocumentResultCollection<>(recognizeEntitiesResults, + entitiesResult.getModelVersion(), entitiesResult.getStatistics() == null ? null + : toBatchStatistics(entitiesResult.getStatistics())); + } +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java new file mode 100644 index 000000000000..9d87ab08de67 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizeLinkedEntityAsyncClient.java @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics; + +import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl; +import com.azure.ai.textanalytics.implementation.models.DocumentError; +import com.azure.ai.textanalytics.implementation.models.DocumentLinkedEntities; +import com.azure.ai.textanalytics.implementation.models.EntityLinkingResult; +import com.azure.ai.textanalytics.implementation.models.LinkedEntity; +import com.azure.ai.textanalytics.implementation.models.MultiLanguageBatchInput; +import com.azure.ai.textanalytics.models.DocumentResultCollection; +import com.azure.ai.textanalytics.models.LinkedEntityMatch; +import com.azure.ai.textanalytics.models.RecognizeLinkedEntitiesResult; +import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; +import com.azure.ai.textanalytics.models.TextDocumentInput; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.azure.ai.textanalytics.Transforms.mapByIndex; +import static com.azure.ai.textanalytics.Transforms.toBatchStatistics; +import static com.azure.ai.textanalytics.Transforms.toMultiLanguageInput; +import static com.azure.ai.textanalytics.Transforms.toTextAnalyticsError; +import static com.azure.ai.textanalytics.Transforms.toTextDocumentStatistics; + +/** + * Helper class for managing recognize linked entity endpoint. + */ +class RecognizeLinkedEntityAsyncClient { + private final ClientLogger logger = new ClientLogger(RecognizeLinkedEntityAsyncClient.class); + private final TextAnalyticsClientImpl service; + + /** + * Create a {@code RecognizeLinkedEntityAsyncClient} that sends requests to the Text Analytics services's recognize + * linked entity endpoint. + * + * @param service The proxy service used to perform REST calls. + */ + RecognizeLinkedEntityAsyncClient(TextAnalyticsClientImpl service) { + this.service = service; + } + + Mono> recognizeLinkedEntitiesWithResponse(String text, String language, + Context context) { + Objects.requireNonNull(text, "'text' cannot be null."); + + return recognizeBatchLinkedEntitiesWithResponse( + Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) + .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + } + + Mono>> recognizeLinkedEntitiesWithResponse( + List textInputs, String language, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + List documentInputs = mapByIndex(textInputs, (index, value) -> + new TextDocumentInput(index, value, language)); + return recognizeBatchLinkedEntitiesWithResponse(documentInputs, null, context); + } + + Mono>> recognizeBatchLinkedEntitiesWithResponse( + List textInputs, TextAnalyticsRequestOptions options, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() + .setDocuments(toMultiLanguageInput(textInputs)); + return service.entitiesLinkingWithRestResponseAsync( + batchInput, + options == null ? null : options.getModelVersion(), + options == null ? null : options.showStatistics(), context) + .doOnSubscribe(ignoredValue -> logger.info("A batch of linked entities input - {}", textInputs.toString())) + .doOnSuccess(response -> logger.info("A batch of linked entities output - {}", response.getValue())) + .doOnError(error -> logger.warning("Failed to recognize linked entities - {}", error)) + .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); + } + + + private List mapLinkedEntity(List linkedEntities) { + List linkedEntitiesList = new ArrayList<>(); + for (LinkedEntity linkedEntity : linkedEntities) { + linkedEntitiesList.add(new com.azure.ai.textanalytics.models.LinkedEntity(linkedEntity.getName(), + linkedEntity.getMatches().stream().map(match -> + new LinkedEntityMatch(match.getText(), match.getScore(), match.getLength(), + match.getOffset())).collect(Collectors.toList()), linkedEntity.getLanguage(), + linkedEntity.getId(), linkedEntity.getUrl(), linkedEntity.getDataSource())); + } + return linkedEntitiesList; + } + + /** + * Helper method to convert the service response of {@link EntityLinkingResult} to {@link DocumentResultCollection}. + * + * @param entityLinkingResult the {@link EntityLinkingResult} returned by the service. + * + * @return the {@link DocumentResultCollection} of {@link RecognizeLinkedEntitiesResult} to be returned by the SDK. + */ + private DocumentResultCollection toDocumentResultCollection( + final EntityLinkingResult entityLinkingResult) { + List linkedEntitiesResults = new ArrayList<>(); + for (DocumentLinkedEntities documentLinkedEntities : entityLinkingResult.getDocuments()) { + linkedEntitiesResults.add(new RecognizeLinkedEntitiesResult(documentLinkedEntities.getId(), + documentLinkedEntities.getStatistics() == null ? null + : toTextDocumentStatistics(documentLinkedEntities.getStatistics()), + null, mapLinkedEntity(documentLinkedEntities.getEntities()))); + } + for (DocumentError documentError : entityLinkingResult.getErrors()) { + final com.azure.ai.textanalytics.models.TextAnalyticsError error = + toTextAnalyticsError(documentError.getError()); + linkedEntitiesResults.add(new RecognizeLinkedEntitiesResult(documentError.getId(), null, error, null)); + } + + return new DocumentResultCollection<>(linkedEntitiesResults, + entityLinkingResult.getModelVersion(), entityLinkingResult.getStatistics() == null ? null + : toBatchStatistics(entityLinkingResult.getStatistics())); + } + + +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java new file mode 100644 index 000000000000..781432dbd2c9 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/RecognizePiiEntityAsyncClient.java @@ -0,0 +1,113 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics; + +import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl; +import com.azure.ai.textanalytics.implementation.models.DocumentEntities; +import com.azure.ai.textanalytics.implementation.models.DocumentError; +import com.azure.ai.textanalytics.implementation.models.EntitiesResult; +import com.azure.ai.textanalytics.implementation.models.MultiLanguageBatchInput; +import com.azure.ai.textanalytics.models.DocumentResultCollection; +import com.azure.ai.textanalytics.models.NamedEntity; +import com.azure.ai.textanalytics.models.RecognizePiiEntitiesResult; +import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; +import com.azure.ai.textanalytics.models.TextDocumentInput; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.SimpleResponse; +import com.azure.core.util.Context; +import com.azure.core.util.logging.ClientLogger; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.azure.ai.textanalytics.Transforms.mapByIndex; +import static com.azure.ai.textanalytics.Transforms.toBatchStatistics; +import static com.azure.ai.textanalytics.Transforms.toMultiLanguageInput; +import static com.azure.ai.textanalytics.Transforms.toTextAnalyticsError; +import static com.azure.ai.textanalytics.Transforms.toTextDocumentStatistics; + +/** + * Helper class for managing recognize pii entity endpoint. + */ +class RecognizePiiEntityAsyncClient { + private final ClientLogger logger = new ClientLogger(RecognizePiiEntityAsyncClient.class); + private final TextAnalyticsClientImpl service; + + /** + * Create a {@code RecognizePiiEntityAsyncClient} that sends requests to the Text Analytics services's recognize pii + * entity endpoint. + * + * @param service The proxy service used to perform REST calls. + */ + RecognizePiiEntityAsyncClient(TextAnalyticsClientImpl service) { + this.service = service; + } + + Mono> recognizePiiEntitiesWithResponse(String text, String language, + Context context) { + Objects.requireNonNull(text, "'text' cannot be null."); + + return recognizeBatchPiiEntitiesWithResponse( + Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) + .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); + } + + Mono>> recognizePiiEntitiesWithResponse( + List textInputs, String language, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + + List documentInputs = mapByIndex(textInputs, (index, value) -> + new TextDocumentInput(index, value, language)); + return recognizeBatchPiiEntitiesWithResponse(documentInputs, null, context); + } + + Mono>> recognizeBatchPiiEntitiesWithResponse( + List textInputs, TextAnalyticsRequestOptions options, Context context) { + Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); + final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() + .setDocuments(toMultiLanguageInput(textInputs)); + return service.entitiesRecognitionPiiWithRestResponseAsync( + batchInput, + options == null ? null : options.getModelVersion(), + options == null ? null : options.showStatistics(), context) + .doOnSubscribe(ignoredValue -> logger.info("A batch of PII entities input - {}", textInputs.toString())) + .doOnSuccess(response -> logger.info("A batch of PII entities output - {}", response.getValue())) + .doOnError(error -> logger.warning("Failed to recognize PII entities - {}", error)) + .map(response -> new SimpleResponse<>(response, toPiiDocumentResultCollection(response.getValue()))); + } + + /** + * Helper method to convert the service response of {@link EntitiesResult} to {@link DocumentResultCollection}. + * + * @param entitiesResult the {@link EntitiesResult} returned by the service. + * + * @return the {@link DocumentResultCollection} of {@link RecognizePiiEntitiesResult} to be returned by the SDK. + */ + private DocumentResultCollection toPiiDocumentResultCollection( + final EntitiesResult entitiesResult) { + List recognizePiiEntitiesResults = new ArrayList<>(); + for (DocumentEntities documentEntities : entitiesResult.getDocuments()) { + recognizePiiEntitiesResults.add(new RecognizePiiEntitiesResult(documentEntities.getId(), + documentEntities.getStatistics() == null ? null + : toTextDocumentStatistics(documentEntities.getStatistics()), + null, documentEntities.getEntities().stream().map(entity -> + new NamedEntity(entity.getText(), entity.getType(), entity.getSubtype(), entity.getOffset(), + entity.getLength(), entity.getScore())).collect(Collectors.toList()))); + } + + for (DocumentError documentError : entitiesResult.getErrors()) { + final com.azure.ai.textanalytics.models.TextAnalyticsError error = + toTextAnalyticsError(documentError.getError()); + recognizePiiEntitiesResults.add(new RecognizePiiEntitiesResult(documentError.getId(), null, error, null)); + } + + return new DocumentResultCollection<>(recognizePiiEntitiesResults, + entitiesResult.getModelVersion(), entitiesResult.getStatistics() == null ? null + : toBatchStatistics(entitiesResult.getStatistics())); + } +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java index c969f8c0d74c..34e03ee54dd3 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClient.java @@ -4,61 +4,26 @@ package com.azure.ai.textanalytics; import com.azure.ai.textanalytics.implementation.TextAnalyticsClientImpl; -import com.azure.ai.textanalytics.implementation.models.DocumentEntities; -import com.azure.ai.textanalytics.implementation.models.DocumentError; -import com.azure.ai.textanalytics.implementation.models.DocumentKeyPhrases; -import com.azure.ai.textanalytics.implementation.models.DocumentLanguage; -import com.azure.ai.textanalytics.implementation.models.DocumentLinkedEntities; -import com.azure.ai.textanalytics.implementation.models.DocumentSentiment; -import com.azure.ai.textanalytics.implementation.models.DocumentStatistics; -import com.azure.ai.textanalytics.implementation.models.EntitiesResult; -import com.azure.ai.textanalytics.implementation.models.EntityLinkingResult; -import com.azure.ai.textanalytics.implementation.models.LanguageBatchInput; -import com.azure.ai.textanalytics.implementation.models.LanguageInput; -import com.azure.ai.textanalytics.implementation.models.LanguageResult; -import com.azure.ai.textanalytics.implementation.models.LinkedEntity; -import com.azure.ai.textanalytics.implementation.models.MultiLanguageBatchInput; -import com.azure.ai.textanalytics.implementation.models.MultiLanguageInput; -import com.azure.ai.textanalytics.implementation.models.RequestStatistics; -import com.azure.ai.textanalytics.implementation.models.SentimentConfidenceScorePerLabel; -import com.azure.ai.textanalytics.implementation.models.SentimentResponse; -import com.azure.ai.textanalytics.implementation.models.TextAnalyticsError; import com.azure.ai.textanalytics.models.AnalyzeSentimentResult; import com.azure.ai.textanalytics.models.DetectLanguageInput; import com.azure.ai.textanalytics.models.DetectLanguageResult; -import com.azure.ai.textanalytics.models.DetectedLanguage; import com.azure.ai.textanalytics.models.DocumentResultCollection; -import com.azure.ai.textanalytics.models.ErrorCodeValue; import com.azure.ai.textanalytics.models.ExtractKeyPhraseResult; -import com.azure.ai.textanalytics.models.LinkedEntityMatch; -import com.azure.ai.textanalytics.models.NamedEntity; import com.azure.ai.textanalytics.models.RecognizeEntitiesResult; import com.azure.ai.textanalytics.models.RecognizeLinkedEntitiesResult; import com.azure.ai.textanalytics.models.RecognizePiiEntitiesResult; import com.azure.ai.textanalytics.models.TextAnalyticsClientOptions; import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; -import com.azure.ai.textanalytics.models.TextDocumentBatchStatistics; import com.azure.ai.textanalytics.models.TextDocumentInput; -import com.azure.ai.textanalytics.models.TextDocumentStatistics; -import com.azure.ai.textanalytics.models.TextSentiment; -import com.azure.ai.textanalytics.models.TextSentimentClass; import com.azure.core.annotation.ReturnType; import com.azure.core.annotation.ServiceClient; import com.azure.core.annotation.ServiceMethod; import com.azure.core.http.rest.Response; -import com.azure.core.http.rest.SimpleResponse; -import com.azure.core.util.Context; import com.azure.core.util.FluxUtil; import com.azure.core.util.logging.ClientLogger; import reactor.core.publisher.Mono; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Objects; -import java.util.function.BiFunction; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import static com.azure.core.util.FluxUtil.monoError; import static com.azure.core.util.FluxUtil.withContext; @@ -82,6 +47,12 @@ public final class TextAnalyticsAsyncClient { private final TextAnalyticsServiceVersion serviceVersion; private final String defaultCountryHint; private final String defaultLanguage; + final DetectLanguageAsyncClient detectLanguageAsyncClient; + final AnalyzeSentimentAsyncClient analyzeSentimentAsyncClient; + final ExtractKeyPhraseAsyncClient extractKeyPhraseAsyncClient; + final RecognizeEntityAsyncClient recognizeEntityAsyncClient; + final RecognizePiiEntityAsyncClient recognizePiiEntityAsyncClient; + final RecognizeLinkedEntityAsyncClient recognizeLinkedEntityAsyncClient; /** * Create a {@code TextAnalyticsAsyncClient} that sends requests to the Text Analytics services's endpoint. Each @@ -100,6 +71,12 @@ public final class TextAnalyticsAsyncClient { this.serviceVersion = serviceVersion; defaultCountryHint = clientOptions == null ? null : clientOptions.getDefaultCountryHint(); defaultLanguage = clientOptions == null ? null : clientOptions.getDefaultLanguage(); + this.detectLanguageAsyncClient = new DetectLanguageAsyncClient(service); + this.analyzeSentimentAsyncClient = new AnalyzeSentimentAsyncClient(service); + this.extractKeyPhraseAsyncClient = new ExtractKeyPhraseAsyncClient(service); + this.recognizeEntityAsyncClient = new RecognizeEntityAsyncClient(service); + this.recognizePiiEntityAsyncClient = new RecognizePiiEntityAsyncClient(service); + this.recognizeLinkedEntityAsyncClient = new RecognizeLinkedEntityAsyncClient(service); } /** @@ -164,20 +141,13 @@ public Mono detectLanguage(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Mono> detectLanguageWithResponse(String text, String countryHint) { try { - return withContext(context -> detectLanguageWithResponse(text, countryHint, context)); + return withContext(context -> + detectLanguageAsyncClient.detectLanguageWithResponse(text, countryHint, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono> detectLanguageWithResponse(String text, String countryHint, Context context) { - Objects.requireNonNull(text, "'text' cannot be null."); - List languageInputs = Collections.singletonList(new DetectLanguageInput("0", - text, countryHint)); - return detectBatchLanguagesWithResponse(languageInputs, null, context).map(response -> - new SimpleResponse<>(response, response.getValue().iterator().next())); - } - /** * Returns the detected language for a batch of input. * @@ -213,21 +183,13 @@ public Mono> detectLanguages(List public Mono>> detectLanguagesWithResponse( List textInputs, String countryHint) { try { - return withContext(context -> detectLanguagesWithResponse(textInputs, countryHint, context)); + return withContext(context -> detectLanguageAsyncClient.detectLanguagesWithResponse(textInputs, countryHint, + context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> detectLanguagesWithResponse(List textInputs, - String countryHint, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - List detectLanguageInputs = mapByIndex(textInputs, (index, value) -> - new DetectLanguageInput(index, value, countryHint)); - - return detectBatchLanguagesWithResponse(detectLanguageInputs, null, context); - } - /** * Returns the detected language for a batch of input. * @@ -265,30 +227,12 @@ public Mono>> detectBatc List textInputs, TextAnalyticsRequestOptions options) { try { return withContext( - context -> detectBatchLanguagesWithResponse(textInputs, options, context)); + context -> detectLanguageAsyncClient.detectBatchLanguagesWithResponse(textInputs, options, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> detectBatchLanguagesWithResponse( - List textInputs, TextAnalyticsRequestOptions options, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - final LanguageBatchInput languageBatchInput = new LanguageBatchInput() - .setDocuments(textInputs.stream().map(detectLanguageInput -> new LanguageInput() - .setId(detectLanguageInput.getId()).setText(detectLanguageInput.getText()) - .setCountryHint(detectLanguageInput.getCountryHint())).collect(Collectors.toList())); - - return service.languagesWithRestResponseAsync( - languageBatchInput, options == null ? null : options.getModelVersion(), - options == null ? null : options.showStatistics(), context) - .doOnSubscribe(ignoredValue -> logger.info("A batch of language input - {}", textInputs.toString())) - .doOnSuccess(response -> logger.info("A batch of detected language output - {}", response.getValue())) - .doOnError(error -> logger.warning("Failed to detected languages - {}", error)) - .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); - } - // Named Entity /** * Returns a list of general named entities in the provided text. For a list of supported entity types, check: @@ -327,21 +271,13 @@ public Mono recognizeEntities(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Mono> recognizeEntitiesWithResponse(String text, String language) { try { - return withContext(context -> recognizeEntitiesWithResponse(text, language, context)); + return withContext(context -> + recognizeEntityAsyncClient.recognizeEntitiesWithResponse(text, language, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono> recognizeEntitiesWithResponse(String text, String language, - Context context) { - Objects.requireNonNull(text, "'text' cannot be null."); - - return recognizeBatchEntitiesWithResponse( - Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); - } - /** * Returns a list of general named entities for the provided list of texts. * @@ -377,21 +313,13 @@ public Mono> recognizeEntities public Mono>> recognizeEntitiesWithResponse( List textInputs, String language) { try { - return withContext(context -> recognizeEntitiesWithResponse(textInputs, language, context)); + return withContext(context -> recognizeEntityAsyncClient.recognizeEntitiesWithResponse(textInputs, language, + context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> recognizeEntitiesWithResponse( - List textInputs, String language, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - List documentInputs = mapByIndex(textInputs, (index, value) -> - new TextDocumentInput(index, value, language)); - return recognizeBatchEntitiesWithResponse(documentInputs, null, context); - } - /** * Returns a list of general named entities for the provided list of text inputs. * @@ -428,28 +356,13 @@ public Mono> recognizeBatchEnt public Mono>> recognizeBatchEntitiesWithResponse( List textInputs, TextAnalyticsRequestOptions options) { try { - return withContext(context -> recognizeBatchEntitiesWithResponse(textInputs, options, context)); + return withContext(context -> + recognizeEntityAsyncClient.recognizeBatchEntitiesWithResponse(textInputs, options, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> recognizeBatchEntitiesWithResponse( - List textInputs, TextAnalyticsRequestOptions options, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() - .setDocuments(convertToMultiLanguageInput(textInputs)); - return service.entitiesRecognitionGeneralWithRestResponseAsync( - batchInput, - options == null ? null : options.getModelVersion(), - options == null ? null : options.showStatistics(), context) - .doOnSubscribe(ignoredValue -> logger.info("A batch of named entities input - {}", textInputs.toString())) - .doOnSuccess(response -> logger.info("A batch of named entities output - {}", response.getValue())) - .doOnError(error -> logger.warning("Failed to named entities - {}", error)) - .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); - } - // PII Entity /** * Returns a list of personal information entities ("SSN", "Bank Account", etc) in the text. For the list of @@ -488,21 +401,13 @@ public Mono recognizePiiEntities(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Mono> recognizePiiEntitiesWithResponse(String text, String language) { try { - return withContext(context -> recognizePiiEntitiesWithResponse(text, language, context)); + return withContext(context -> recognizePiiEntityAsyncClient.recognizePiiEntitiesWithResponse(text, language, + context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono> recognizePiiEntitiesWithResponse(String text, String language, - Context context) { - Objects.requireNonNull(text, "'text' cannot be null."); - - return recognizeBatchPiiEntitiesWithResponse( - Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); - } - /** * Returns a list of personal information entities ("SSN", "Bank Account", etc) in the list of texts. For the list * of supported entity types, check: . For a list of enabled languages, @@ -543,20 +448,8 @@ public Mono> recognizePiiEn public Mono>> recognizePiiEntitiesWithResponse( List textInputs, String language) { try { - return withContext(context -> recognizePiiEntitiesWithResponse(textInputs, language, context)); - } catch (RuntimeException ex) { - return monoError(logger, ex); - } - } - - Mono>> recognizePiiEntitiesWithResponse( - List textInputs, String language, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - List documentInputs = mapByIndex(textInputs, (index, value) -> - new TextDocumentInput(index, value, language)); - try { - return recognizeBatchPiiEntitiesWithResponse(documentInputs, null, context); + return withContext(context -> recognizePiiEntityAsyncClient.recognizePiiEntitiesWithResponse(textInputs, + language, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } @@ -602,27 +495,13 @@ public Mono> recognizeBatch public Mono>> recognizeBatchPiiEntitiesWithResponse( List textInputs, TextAnalyticsRequestOptions options) { try { - return withContext(context -> recognizeBatchPiiEntitiesWithResponse(textInputs, options, context)); + return withContext(context -> + recognizePiiEntityAsyncClient.recognizeBatchPiiEntitiesWithResponse(textInputs, options, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> recognizeBatchPiiEntitiesWithResponse( - List textInputs, TextAnalyticsRequestOptions options, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() - .setDocuments(convertToMultiLanguageInput(textInputs)); - return service.entitiesRecognitionPiiWithRestResponseAsync( - batchInput, - options == null ? null : options.getModelVersion(), - options == null ? null : options.showStatistics(), context) - .doOnSubscribe(ignoredValue -> logger.info("A batch of PII entities input - {}", textInputs.toString())) - .doOnSuccess(response -> logger.info("A batch of PII entities output - {}", response.getValue())) - .doOnError(error -> logger.warning("Failed to PII entities - {}", error)) - .map(response -> new SimpleResponse<>(response, toPiiDocumentResultCollection(response.getValue()))); - } - // Linked Entity /** * Returns a list of recognized entities with links to a well-known knowledge base for the provided text. See @@ -660,21 +539,13 @@ public Mono recognizeLinkedEntities(String text) public Mono> recognizeLinkedEntitiesWithResponse(String text, String language) { try { - return withContext(context -> recognizeLinkedEntitiesWithResponse(text, language, context)); + return withContext(context -> recognizeLinkedEntityAsyncClient.recognizeLinkedEntitiesWithResponse(text, + language, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono> recognizeLinkedEntitiesWithResponse(String text, String language, - Context context) { - Objects.requireNonNull(text, "'text' cannot be null."); - - return recognizeBatchLinkedEntitiesWithResponse( - Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); - } - /** * Returns a list of recognized entities with links to a well-known knowledge base for the list of texts. See * for supported languages in Text Analytics API. @@ -714,20 +585,8 @@ public Mono> recognizeLi public Mono>> recognizeLinkedEntitiesWithResponse( List textInputs, String language) { try { - return withContext(context -> recognizeLinkedEntitiesWithResponse(textInputs, language, context)); - } catch (RuntimeException ex) { - return monoError(logger, ex); - } - } - - Mono>> recognizeLinkedEntitiesWithResponse( - List textInputs, String language, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - List documentInputs = mapByIndex(textInputs, (index, value) -> - new TextDocumentInput(index, value, language)); - try { - return recognizeBatchLinkedEntitiesWithResponse(documentInputs, null, context); + return withContext(context -> + recognizeLinkedEntityAsyncClient.recognizeLinkedEntitiesWithResponse(textInputs, language, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } @@ -772,29 +631,13 @@ public Mono> recognizeBa recognizeBatchLinkedEntitiesWithResponse(List textInputs, TextAnalyticsRequestOptions options) { try { - return withContext(context -> recognizeBatchLinkedEntitiesWithResponse(textInputs, options, context)); + return withContext(context -> recognizeLinkedEntityAsyncClient.recognizeBatchLinkedEntitiesWithResponse( + textInputs, options, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> recognizeBatchLinkedEntitiesWithResponse( - List textInputs, TextAnalyticsRequestOptions options, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() - .setDocuments(convertToMultiLanguageInput(textInputs)); - return service.entitiesLinkingWithRestResponseAsync( - batchInput, - options == null ? null : options.getModelVersion(), - options == null ? null : options.showStatistics(), context) - .doOnSubscribe(ignoredValue -> logger.info("A batch of linked entities input - {}", textInputs.toString())) - .doOnSuccess(response -> logger.info("A batch of linked entities output - {}", response.getValue())) - .doOnError(error -> logger.warning("Failed to linked entities - {}", error)) - .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); - } - - // Key Phrases /** * Returns a list of strings denoting the key phrases in the input text. @@ -830,21 +673,13 @@ public Mono extractKeyPhrases(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Mono> extractKeyPhrasesWithResponse(String text, String language) { try { - return withContext(context -> extractKeyPhrasesWithResponse(text, language, context)); + return withContext(context -> extractKeyPhraseAsyncClient.extractKeyPhrasesWithResponse(text, language, + context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono> extractKeyPhrasesWithResponse(String text, String language, - Context context) { - Objects.requireNonNull(text, "'text' cannot be null."); - - return extractBatchKeyPhrasesWithResponse( - Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); - } - /** * Returns a list of strings denoting the key phrases in the input text. * @@ -881,20 +716,8 @@ public Mono> extractKeyPhrases( public Mono>> extractKeyPhrasesWithResponse( List textInputs, String language) { try { - return withContext(context -> extractKeyPhrasesWithResponse(textInputs, language, context)); - } catch (RuntimeException ex) { - return monoError(logger, ex); - } - } - - Mono>> extractKeyPhrasesWithResponse( - List textInputs, String language, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - List documentInputs = mapByIndex(textInputs, (index, value) -> - new TextDocumentInput(index, value, language)); - try { - return extractBatchKeyPhrasesWithResponse(documentInputs, null, context); + return withContext(context -> extractKeyPhraseAsyncClient.extractKeyPhrasesWithResponse(textInputs, + language, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } @@ -937,48 +760,13 @@ public Mono> extractBatchKeyPhr public Mono>> extractBatchKeyPhrasesWithResponse( List textInputs, TextAnalyticsRequestOptions options) { try { - return withContext(context -> extractBatchKeyPhrasesWithResponse(textInputs, options, context)); + return withContext(context -> + extractKeyPhraseAsyncClient.extractBatchKeyPhrasesWithResponse(textInputs, options, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> extractBatchKeyPhrasesWithResponse( - List textInputs, TextAnalyticsRequestOptions options, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() - .setDocuments(convertToMultiLanguageInput(textInputs)); - return service.keyPhrasesWithRestResponseAsync( - batchInput, - options == null ? null : options.getModelVersion(), - options == null ? null : options.showStatistics(), context) - .doOnSubscribe(ignoredValue -> logger.info("A batch of key phrases input - {}", textInputs.toString())) - .doOnSuccess(response -> logger.info("A batch of key phrases output - {}", response.getValue())) - .doOnError(error -> logger.warning("Failed to key phrases - {}", error)) - .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); - } - - private DocumentResultCollection toDocumentResultCollection( - final com.azure.ai.textanalytics.implementation.models.KeyPhraseResult keyPhraseResult) { - List keyPhraseResultList = new ArrayList<>(); - for (DocumentKeyPhrases documentKeyPhrases : keyPhraseResult.getDocuments()) { - keyPhraseResultList.add(new ExtractKeyPhraseResult(documentKeyPhrases.getId(), - documentKeyPhrases.getStatistics() == null ? null - : convertToTextDocumentStatistics(documentKeyPhrases.getStatistics()), null, - documentKeyPhrases.getKeyPhrases())); - } - - for (DocumentError documentError : keyPhraseResult.getErrors()) { - final com.azure.ai.textanalytics.models.TextAnalyticsError error = convertToError(documentError.getError()); - keyPhraseResultList.add(new ExtractKeyPhraseResult(documentError.getId(), null, error, null)); - } - - return new DocumentResultCollection<>(keyPhraseResultList, - keyPhraseResult.getModelVersion(), keyPhraseResult.getStatistics() == null ? null - : mapBatchStatistics(keyPhraseResult.getStatistics())); - } - // Sentiment /** * Returns a sentiment prediction, as well as sentiment scores for each sentiment class (Positive, Negative, and @@ -1015,20 +803,13 @@ public Mono analyzeSentiment(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Mono> analyzeSentimentWithResponse(String text, String language) { try { - return withContext(context -> analyzeSentimentWithResponse(text, language, context)); + return withContext(context -> + analyzeSentimentAsyncClient.analyzeSentimentWithResponse(text, language, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono> analyzeSentimentWithResponse(String text, String language, Context context) { - Objects.requireNonNull(text, "'text' cannot be null."); - - return analyzeBatchSentimentWithResponse( - Collections.singletonList(new TextDocumentInput("0", text, language)), null, context) - .map(response -> new SimpleResponse<>(response, response.getValue().iterator().next())); - } - /** * Returns a sentiment prediction, as well as sentiment scores for each sentiment class (Positive, Negative, and * Neutral) for the document and each sentence within it. @@ -1066,21 +847,13 @@ public Mono> analyzeSentiment(L public Mono>> analyzeSentimentWithResponse( List textInputs, String language) { try { - return withContext(context -> analyzeSentimentWithResponse(textInputs, language, context)); + return withContext(context -> analyzeSentimentAsyncClient.analyzeSentimentWithResponse(textInputs, language, + context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - Mono>> analyzeSentimentWithResponse( - List textInputs, String language, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - List documentInputs = mapByIndex(textInputs, (index, value) -> - new TextDocumentInput(index, value, language)); - return analyzeBatchSentimentWithResponse(documentInputs, null, context); - } - /** * Returns a sentiment prediction, as well as sentiment scores for each sentiment class (Positive, Negative, and * Neutral) for the document and each sentence within it. @@ -1119,267 +892,10 @@ public Mono> analyzeBatchSentim public Mono>> analyzeBatchSentimentWithResponse( List textInputs, TextAnalyticsRequestOptions options) { try { - return withContext(context -> analyzeBatchSentimentWithResponse(textInputs, options, context)); + return withContext(context -> analyzeSentimentAsyncClient.analyzeBatchSentimentWithResponse(textInputs, + options, context)); } catch (RuntimeException ex) { return monoError(logger, ex); } } - - Mono>> analyzeBatchSentimentWithResponse( - List textInputs, TextAnalyticsRequestOptions options, Context context) { - Objects.requireNonNull(textInputs, "'textInputs' cannot be null."); - - final MultiLanguageBatchInput batchInput = new MultiLanguageBatchInput() - .setDocuments(convertToMultiLanguageInput(textInputs)); - return service.sentimentWithRestResponseAsync( - batchInput, - options == null ? null : options.getModelVersion(), - options == null ? null : options.showStatistics(), context) - .doOnSubscribe(ignoredValue -> logger.info("A batch of text sentiment input - {}", textInputs.toString())) - .doOnSuccess(response -> logger.info("A batch of text sentiment output - {}", response)) - .doOnError(error -> logger.warning("Failed to text sentiment - {}", error)) - .map(response -> new SimpleResponse<>(response, toDocumentResultCollection(response.getValue()))); - } - - private List convertToMultiLanguageInput(List textInputs) { - List multiLanguageInputs = new ArrayList<>(); - for (TextDocumentInput textDocumentInput : textInputs) { - multiLanguageInputs.add(new MultiLanguageInput().setId(textDocumentInput.getId()) - .setText(textDocumentInput.getText()).setLanguage(textDocumentInput.getLanguage())); - } - return multiLanguageInputs; - } - - /** - * Helper method to convert the service response of {@link SentimentResponse} to {@link DocumentResultCollection}. - * - * @param sentimentResponse the {@link SentimentResponse} returned by the service. - * - * @return the {@link DocumentResultCollection} of {@link AnalyzeSentimentResult} to be returned by the SDK. - */ - private DocumentResultCollection toDocumentResultCollection( - final SentimentResponse sentimentResponse) { - List analyzeSentimentResults = new ArrayList<>(); - for (DocumentSentiment documentSentiment : sentimentResponse.getDocuments()) { - analyzeSentimentResults.add(convertToTextSentimentResult(documentSentiment)); - } - for (DocumentError documentError : sentimentResponse.getErrors()) { - final com.azure.ai.textanalytics.models.TextAnalyticsError error = convertToError(documentError.getError()); - analyzeSentimentResults.add(new AnalyzeSentimentResult(documentError.getId(), null, error, null, - null)); - } - return new DocumentResultCollection<>(analyzeSentimentResults, - sentimentResponse.getModelVersion(), sentimentResponse.getStatistics() == null ? null - : mapBatchStatistics(sentimentResponse.getStatistics())); - } - - private AnalyzeSentimentResult convertToTextSentimentResult(final DocumentSentiment documentSentiment) { - // Document text sentiment - final TextSentimentClass documentSentimentClass = TextSentimentClass.fromString(documentSentiment. - getSentiment().toString()); - if (documentSentimentClass == null) { - // Not throw exception for an invalid Sentiment type because we should not skip processing the - // other response. It is a service issue. - logger.logExceptionAsWarning( - new RuntimeException(String.format("'%s' is not valid text sentiment.", - documentSentiment.getSentiment()))); - } - final SentimentConfidenceScorePerLabel confidenceScorePerLabel = documentSentiment.getDocumentScores(); - - // Sentence text sentiment - final List sentenceSentimentTexts = documentSentiment.getSentences().stream() - .map(sentenceSentiment -> { - TextSentimentClass sentimentClass = TextSentimentClass.fromString(sentenceSentiment - .getSentiment().toString()); - if (sentimentClass == null) { - // Not throw exception for an invalid Sentiment type because we should not skip processing the - // other response. It is a service issue. - logger.logExceptionAsWarning( - new RuntimeException(String.format("'%s' is not valid text sentiment.", - sentenceSentiment.getSentiment()))); - } - SentimentConfidenceScorePerLabel confidenceScorePerSentence = sentenceSentiment.getSentenceScores(); - - return new TextSentiment(sentimentClass, confidenceScorePerSentence.getNegative(), - confidenceScorePerSentence.getNeutral(), confidenceScorePerSentence.getPositive(), - sentenceSentiment.getLength(), sentenceSentiment.getOffset()); - - }).collect(Collectors.toList()); - - return new AnalyzeSentimentResult(documentSentiment.getId(), - documentSentiment.getStatistics() == null ? null - : convertToTextDocumentStatistics(documentSentiment.getStatistics()), null, - new TextSentiment(documentSentimentClass, confidenceScorePerLabel.getNegative(), - confidenceScorePerLabel.getNeutral(), confidenceScorePerLabel.getPositive(), - sentenceSentimentTexts.stream().mapToInt(TextSentiment::getLength).sum(), 0), - sentenceSentimentTexts); - } - - /** - * Helper method to convert the service response of {@link LanguageResult} to {@link DocumentResultCollection}. - * - * @param languageResult the {@link LanguageResult} returned by the service. - * - * @return the {@link DocumentResultCollection} of {@link DetectLanguageResult} to be returned by the SDK. - */ - private DocumentResultCollection toDocumentResultCollection( - final LanguageResult languageResult) { - - final List detectLanguageResults = new ArrayList<>(); - for (DocumentLanguage documentLanguage : languageResult.getDocuments()) { - DetectedLanguage primaryLanguage = null; - if (documentLanguage.getDetectedLanguages().size() >= 1) { - com.azure.ai.textanalytics.implementation.models.DetectedLanguage detectedLanguageResult = - documentLanguage.getDetectedLanguages().get(0); - primaryLanguage = new DetectedLanguage(detectedLanguageResult.getName(), - detectedLanguageResult.getIso6391Name(), detectedLanguageResult.getScore()); - } - detectLanguageResults.add(new DetectLanguageResult(documentLanguage.getId(), - documentLanguage.getStatistics() == null - ? null : convertToTextDocumentStatistics(documentLanguage.getStatistics()), - null, - primaryLanguage, - documentLanguage.getDetectedLanguages().stream().map(detectedLanguage -> - new DetectedLanguage(detectedLanguage.getName(), detectedLanguage.getIso6391Name(), - detectedLanguage.getScore())).collect(Collectors.toList()))); - } - - for (DocumentError documentError : languageResult.getErrors()) { - com.azure.ai.textanalytics.models.TextAnalyticsError error = convertToError(documentError.getError()); - detectLanguageResults.add( - new DetectLanguageResult(documentError.getId(), null, error, null, null)); - } - - return new DocumentResultCollection<>(detectLanguageResults, languageResult.getModelVersion(), - languageResult.getStatistics() == null ? null : mapBatchStatistics(languageResult.getStatistics())); - } - - /** - * Helper method to convert the service response of {@link EntitiesResult} to {@link DocumentResultCollection}. - * - * @param entitiesResult the {@link EntitiesResult} returned by the service. - * - * @return the {@link DocumentResultCollection} of {@link DetectLanguageResult} to be returned by the SDK. - */ - private DocumentResultCollection toDocumentResultCollection( - final EntitiesResult entitiesResult) { - List recognizeEntitiesResults = new ArrayList<>(); - for (DocumentEntities documentEntities : entitiesResult.getDocuments()) { - recognizeEntitiesResults.add(new RecognizeEntitiesResult(documentEntities.getId(), - documentEntities.getStatistics() == null ? null - : convertToTextDocumentStatistics(documentEntities.getStatistics()), - null, documentEntities.getEntities().stream().map(entity -> - new NamedEntity(entity.getText(), entity.getType(), entity.getSubtype(), entity.getOffset(), - entity.getLength(), entity.getScore())).collect(Collectors.toList()))); - } - - for (DocumentError documentError : entitiesResult.getErrors()) { - final com.azure.ai.textanalytics.models.TextAnalyticsError error = convertToError(documentError.getError()); - recognizeEntitiesResults.add(new RecognizeEntitiesResult(documentError.getId(), null, error, null)); - } - - return new DocumentResultCollection<>(recognizeEntitiesResults, - entitiesResult.getModelVersion(), entitiesResult.getStatistics() == null ? null - : mapBatchStatistics(entitiesResult.getStatistics())); - } - - /** - * Helper method to convert the service response of {@link EntitiesResult} to {@link DocumentResultCollection}. - * - * @param entitiesResult the {@link EntitiesResult} returned by the service. - * - * @return the {@link DocumentResultCollection} of {@link RecognizePiiEntitiesResult} to be returned by the SDK. - */ - private DocumentResultCollection toPiiDocumentResultCollection( - final EntitiesResult entitiesResult) { - List recognizePiiEntitiesResults = new ArrayList<>(); - for (DocumentEntities documentEntities : entitiesResult.getDocuments()) { - recognizePiiEntitiesResults.add(new RecognizePiiEntitiesResult(documentEntities.getId(), - documentEntities.getStatistics() == null ? null - : convertToTextDocumentStatistics(documentEntities.getStatistics()), - null, documentEntities.getEntities().stream().map(entity -> - new NamedEntity(entity.getText(), entity.getType(), entity.getSubtype(), entity.getOffset(), - entity.getLength(), entity.getScore())).collect(Collectors.toList()))); - } - - for (DocumentError documentError : entitiesResult.getErrors()) { - final com.azure.ai.textanalytics.models.TextAnalyticsError error = convertToError(documentError.getError()); - recognizePiiEntitiesResults.add(new RecognizePiiEntitiesResult(documentError.getId(), null, error, null)); - } - - return new DocumentResultCollection<>(recognizePiiEntitiesResults, - entitiesResult.getModelVersion(), entitiesResult.getStatistics() == null ? null - : mapBatchStatistics(entitiesResult.getStatistics())); - } - - /** - * Helper method to convert the service response of {@link EntityLinkingResult} to {@link DocumentResultCollection}. - * - * @param entityLinkingResult the {@link EntityLinkingResult} returned by the service. - * - * @return the {@link DocumentResultCollection} of {@link RecognizeLinkedEntitiesResult} to be returned by the SDK. - */ - private DocumentResultCollection toDocumentResultCollection( - final EntityLinkingResult entityLinkingResult) { - List linkedEntitiesResults = new ArrayList<>(); - for (DocumentLinkedEntities documentLinkedEntities : entityLinkingResult.getDocuments()) { - linkedEntitiesResults.add(new RecognizeLinkedEntitiesResult(documentLinkedEntities.getId(), - documentLinkedEntities.getStatistics() == null ? null - : convertToTextDocumentStatistics(documentLinkedEntities.getStatistics()), - null, mapLinkedEntity(documentLinkedEntities.getEntities()))); - } - for (DocumentError documentError : entityLinkingResult.getErrors()) { - final com.azure.ai.textanalytics.models.TextAnalyticsError error = convertToError(documentError.getError()); - linkedEntitiesResults.add(new RecognizeLinkedEntitiesResult(documentError.getId(), null, error, null)); - } - - return new DocumentResultCollection<>(linkedEntitiesResults, - entityLinkingResult.getModelVersion(), entityLinkingResult.getStatistics() == null ? null - : mapBatchStatistics(entityLinkingResult.getStatistics())); - } - - private static List mapByIndex(List textInputs, BiFunction mappingFunction) { - return IntStream.range(0, textInputs.size()) - .mapToObj(index -> mappingFunction.apply(String.valueOf(index), textInputs.get(index))) - .collect(Collectors.toList()); - } - - private TextDocumentStatistics convertToTextDocumentStatistics(DocumentStatistics statistics) { - return new TextDocumentStatistics(statistics.getCharactersCount(), statistics.getTransactionsCount()); - } - - private TextDocumentBatchStatistics mapBatchStatistics(RequestStatistics statistics) { - return new TextDocumentBatchStatistics(statistics.getDocumentsCount(), statistics.getErroneousDocumentsCount(), - statistics.getValidDocumentsCount(), statistics.getTransactionsCount()); - } - - private List mapLinkedEntity(List linkedEntities) { - List linkedEntitiesList = new ArrayList<>(); - for (LinkedEntity linkedEntity : linkedEntities) { - linkedEntitiesList.add(new com.azure.ai.textanalytics.models.LinkedEntity(linkedEntity.getName(), - linkedEntity.getMatches().stream().map(match -> - new LinkedEntityMatch(match.getText(), match.getScore(), match.getLength(), - match.getOffset())).collect(Collectors.toList()), linkedEntity.getLanguage(), - linkedEntity.getId(), linkedEntity.getUrl(), linkedEntity.getDataSource())); - } - return linkedEntitiesList; - } - - private com.azure.ai.textanalytics.models.TextAnalyticsError convertToError(TextAnalyticsError textAnalyticsError) { - return new com.azure.ai.textanalytics.models.TextAnalyticsError( - ErrorCodeValue.fromString(textAnalyticsError.getCode().toString()), textAnalyticsError.getMessage(), - textAnalyticsError.getTarget(), textAnalyticsError.getDetails() == null ? null - : setErrors(textAnalyticsError.getDetails())); - } - - private List setErrors(List details) { - List detailsList = new ArrayList<>(); - for (TextAnalyticsError error : details) { - detailsList.add(new com.azure.ai.textanalytics.models.TextAnalyticsError( - ErrorCodeValue.fromString(error.getCode().toString()), - error.getMessage(), - error.getTarget(), error.getDetails() == null ? null : setErrors(error.getDetails()))); - } - return detailsList; - } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java index a549176746e1..288d93f61489 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/TextAnalyticsClient.java @@ -3,16 +3,16 @@ package com.azure.ai.textanalytics; +import com.azure.ai.textanalytics.models.AnalyzeSentimentResult; import com.azure.ai.textanalytics.models.DetectLanguageInput; import com.azure.ai.textanalytics.models.DetectLanguageResult; import com.azure.ai.textanalytics.models.DocumentResultCollection; import com.azure.ai.textanalytics.models.ExtractKeyPhraseResult; -import com.azure.ai.textanalytics.models.RecognizeLinkedEntitiesResult; import com.azure.ai.textanalytics.models.RecognizeEntitiesResult; +import com.azure.ai.textanalytics.models.RecognizeLinkedEntitiesResult; import com.azure.ai.textanalytics.models.RecognizePiiEntitiesResult; import com.azure.ai.textanalytics.models.TextAnalyticsRequestOptions; import com.azure.ai.textanalytics.models.TextDocumentInput; -import com.azure.ai.textanalytics.models.AnalyzeSentimentResult; import com.azure.core.annotation.ReturnType; import com.azure.core.annotation.ServiceClient; import com.azure.core.annotation.ServiceMethod; @@ -90,7 +90,7 @@ public DetectLanguageResult detectLanguage(String text, String countryHint) { */ @ServiceMethod(returns = ReturnType.SINGLE) public Response detectLanguageWithResponse(String text, String countryHint, Context context) { - return client.detectLanguageWithResponse(text, countryHint, context).block(); + return client.detectLanguageAsyncClient.detectLanguageWithResponse(text, countryHint, context).block(); } /** @@ -122,7 +122,7 @@ public DocumentResultCollection detectLanguages(List> detectLanguagesWithResponse( List textInputs, String countryHint, Context context) { - return client.detectLanguagesWithResponse(textInputs, countryHint, context).block(); + return client.detectLanguageAsyncClient.detectLanguagesWithResponse(textInputs, countryHint, context).block(); } /** @@ -153,11 +153,10 @@ public DocumentResultCollection detectBatchLanguages(List< @ServiceMethod(returns = ReturnType.SINGLE) public Response> detectBatchLanguagesWithResponse( List textInputs, TextAnalyticsRequestOptions options, Context context) { - return client.detectBatchLanguagesWithResponse(textInputs, options, context).block(); + return client.detectLanguageAsyncClient.detectBatchLanguagesWithResponse(textInputs, options, context).block(); } // Named Entity - /** * Returns a list of general named entities in the provided text. * For a list of supported entity types, check: @@ -187,7 +186,7 @@ public RecognizeEntitiesResult recognizeEntities(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Response recognizeEntitiesWithResponse( String text, String language, Context context) { - return client.recognizeEntitiesWithResponse(text, language, context).block(); + return client.recognizeEntityAsyncClient.recognizeEntitiesWithResponse(text, language, context).block(); } /** @@ -218,7 +217,7 @@ public DocumentResultCollection recognizeEntities(List< @ServiceMethod(returns = ReturnType.SINGLE) public Response> recognizeEntitiesWithResponse( List textInputs, String language, Context context) { - return client.recognizeEntitiesWithResponse(textInputs, language, context).block(); + return client.recognizeEntityAsyncClient.recognizeEntitiesWithResponse(textInputs, language, context).block(); } /** @@ -250,7 +249,8 @@ public DocumentResultCollection recognizeBatchEntities( @ServiceMethod(returns = ReturnType.SINGLE) public Response> recognizeBatchEntitiesWithResponse( List textInputs, TextAnalyticsRequestOptions options, Context context) { - return client.recognizeBatchEntitiesWithResponse(textInputs, options, context).block(); + return client.recognizeEntityAsyncClient.recognizeBatchEntitiesWithResponse(textInputs, options, + context).block(); } // PII Entities @@ -286,7 +286,7 @@ public RecognizePiiEntitiesResult recognizePiiEntities(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Response recognizePiiEntitiesWithResponse(String text, String language, Context context) { - return client.recognizePiiEntitiesWithResponse(text, language, context).block(); + return client.recognizePiiEntityAsyncClient.recognizePiiEntitiesWithResponse(text, language, context).block(); } /** @@ -322,7 +322,8 @@ public DocumentResultCollection recognizePiiEntities @ServiceMethod(returns = ReturnType.SINGLE) public Response> recognizePiiEntitiesWithResponse( List textInputs, String language, Context context) { - return client.recognizePiiEntitiesWithResponse(textInputs, language, context).block(); + return client.recognizePiiEntityAsyncClient.recognizePiiEntitiesWithResponse(textInputs, language, + context).block(); } /** @@ -358,7 +359,8 @@ public DocumentResultCollection recognizeBatchPiiEnt @ServiceMethod(returns = ReturnType.SINGLE) public Response> recognizeBatchPiiEntitiesWithResponse( List textInputs, TextAnalyticsRequestOptions options, Context context) { - return client.recognizeBatchPiiEntitiesWithResponse(textInputs, options, context).block(); + return client.recognizePiiEntityAsyncClient.recognizeBatchPiiEntitiesWithResponse(textInputs, options, + context).block(); } // Linked Entities @@ -392,7 +394,8 @@ public RecognizeLinkedEntitiesResult recognizeLinkedEntities(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Response recognizeLinkedEntitiesWithResponse(String text, String language, Context context) { - return client.recognizeLinkedEntitiesWithResponse(text, language, context).block(); + return client.recognizeLinkedEntityAsyncClient.recognizeLinkedEntitiesWithResponse(text, language, + context).block(); } /** @@ -426,7 +429,8 @@ public DocumentResultCollection recognizeLinkedEn @ServiceMethod(returns = ReturnType.SINGLE) public Response> recognizeLinkedEntitiesWithResponse( List textInputs, String language, Context context) { - return client.recognizeLinkedEntitiesWithResponse(textInputs, language, context).block(); + return client.recognizeLinkedEntityAsyncClient.recognizeLinkedEntitiesWithResponse(textInputs, language, + context).block(); } /** @@ -460,11 +464,11 @@ public DocumentResultCollection recognizeBatchLin @ServiceMethod(returns = ReturnType.SINGLE) public Response> recognizeBatchLinkedEntitiesWithResponse( List textInputs, TextAnalyticsRequestOptions options, Context context) { - return client.recognizeBatchLinkedEntitiesWithResponse(textInputs, options, context).block(); + return client.recognizeLinkedEntityAsyncClient.recognizeBatchLinkedEntitiesWithResponse(textInputs, options, + context).block(); } // Key Phrase - /** * Returns a list of strings denoting the key phrases in the input text. * @@ -494,7 +498,7 @@ public ExtractKeyPhraseResult extractKeyPhrases(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Response extractKeyPhrasesWithResponse(String text, String language, Context context) { - return client.extractKeyPhrasesWithResponse(text, language, context).block(); + return client.extractKeyPhraseAsyncClient.extractKeyPhrasesWithResponse(text, language, context).block(); } /** @@ -526,7 +530,7 @@ public DocumentResultCollection extractKeyPhrases(List> extractKeyPhrasesWithResponse( List textInputs, String language, Context context) { - return client.extractKeyPhrasesWithResponse(textInputs, language, context).block(); + return client.extractKeyPhraseAsyncClient.extractKeyPhrasesWithResponse(textInputs, language, context).block(); } /** @@ -558,7 +562,8 @@ public DocumentResultCollection extractBatchKeyPhrases(L @ServiceMethod(returns = ReturnType.SINGLE) public Response> extractBatchKeyPhrasesWithResponse( List textInputs, TextAnalyticsRequestOptions options, Context context) { - return client.extractBatchKeyPhrasesWithResponse(textInputs, options, context).block(); + return client.extractKeyPhraseAsyncClient.extractBatchKeyPhrasesWithResponse(textInputs, options, + context).block(); } // Sentiment @@ -591,7 +596,7 @@ public AnalyzeSentimentResult analyzeSentiment(String text) { @ServiceMethod(returns = ReturnType.SINGLE) public Response analyzeBatchSentimentWithResponse( String text, String language, Context context) { - return client.analyzeSentimentWithResponse(text, language, context).block(); + return client.analyzeSentimentAsyncClient.analyzeSentimentWithResponse(text, language, context).block(); } /** @@ -625,7 +630,7 @@ public DocumentResultCollection analyzeSentiment(List> analyzeSentimentWithResponse( List textInputs, String language, Context context) { - return client.analyzeSentimentWithResponse(textInputs, language, context).block(); + return client.analyzeSentimentAsyncClient.analyzeSentimentWithResponse(textInputs, language, context).block(); } /** @@ -658,6 +663,7 @@ public DocumentResultCollection analyzeBatchSentiment(Li @ServiceMethod(returns = ReturnType.SINGLE) public Response> analyzeBatchSentimentWithResponse( List textInputs, TextAnalyticsRequestOptions options, Context context) { - return client.analyzeBatchSentimentWithResponse(textInputs, options, context).block(); + return client.analyzeSentimentAsyncClient.analyzeBatchSentimentWithResponse(textInputs, options, + context).block(); } } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/Transforms.java b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/Transforms.java new file mode 100644 index 000000000000..bb87131a9018 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/src/main/java/com/azure/ai/textanalytics/Transforms.java @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.textanalytics; + +import com.azure.ai.textanalytics.implementation.models.DocumentStatistics; +import com.azure.ai.textanalytics.implementation.models.MultiLanguageInput; +import com.azure.ai.textanalytics.implementation.models.RequestStatistics; +import com.azure.ai.textanalytics.implementation.models.TextAnalyticsError; +import com.azure.ai.textanalytics.models.ErrorCodeValue; +import com.azure.ai.textanalytics.models.TextDocumentBatchStatistics; +import com.azure.ai.textanalytics.models.TextDocumentInput; +import com.azure.ai.textanalytics.models.TextDocumentStatistics; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * Helper class to convert service level models to SDK exposes models. + */ +class Transforms { + + /** + * Given a list of inputs will apply the indexing function to it and return the updated list. + * + * @param textInputs the inputs to apply the mapping function to. + * @param mappingFunction the function which applies the index to the incoming input value. + * @param the type of items being returned in the list. + * @return The list holding all the generic items combined. + */ + static List mapByIndex(List textInputs, BiFunction mappingFunction) { + return IntStream.range(0, textInputs.size()) + .mapToObj(index -> mappingFunction.apply(String.valueOf(index), textInputs.get(index))) + .collect(Collectors.toList()); + } + + /** + * Convert {@link DocumentStatistics} to {@link TextDocumentStatistics} + * + * @param statistics the {@link DocumentStatistics} provided by the service. + * @return the {@link TextDocumentStatistics} returned by the SDK. + */ + static TextDocumentStatistics toTextDocumentStatistics(DocumentStatistics statistics) { + return new TextDocumentStatistics(statistics.getCharactersCount(), statistics.getTransactionsCount()); + } + + /** + * Convert {@link RequestStatistics} to {@link TextDocumentBatchStatistics} + * + * @param statistics the {@link RequestStatistics} provided by the service. + * @return the {@link TextDocumentBatchStatistics} returned by the SDK. + */ + static TextDocumentBatchStatistics toBatchStatistics(RequestStatistics statistics) { + return new TextDocumentBatchStatistics(statistics.getDocumentsCount(), statistics.getValidDocumentsCount(), + statistics.getErroneousDocumentsCount(), statistics.getTransactionsCount()); + } + + /** + * Convert {@link TextAnalyticsError} to {@link com.azure.ai.textanalytics.models.TextAnalyticsError} + * + * @param textAnalyticsError the {@link TextAnalyticsError} returned by the service. + * @return the {@link com.azure.ai.textanalytics.models.TextAnalyticsError} returned by the SDK. + */ + static com.azure.ai.textanalytics.models.TextAnalyticsError toTextAnalyticsError( + TextAnalyticsError textAnalyticsError) { + return new com.azure.ai.textanalytics.models.TextAnalyticsError( + ErrorCodeValue.fromString(textAnalyticsError.getCode().toString()), textAnalyticsError.getMessage(), + textAnalyticsError.getTarget(), textAnalyticsError.getDetails() == null ? null + : setErrors(textAnalyticsError.getDetails())); + } + + /** + * Convert the incoming input {@link TextDocumentInput} to the service expected {@link MultiLanguageInput}. + * + * @param textInputs the user provided input in {@link TextDocumentInput} + * @return the service required input {@link MultiLanguageInput} + */ + static List toMultiLanguageInput(List textInputs) { + List multiLanguageInputs = new ArrayList<>(); + for (TextDocumentInput textDocumentInput : textInputs) { + multiLanguageInputs.add(new MultiLanguageInput().setId(textDocumentInput.getId()) + .setText(textDocumentInput.getText()).setLanguage(textDocumentInput.getLanguage())); + } + return multiLanguageInputs; + } + + /** + * Helper method to set error details on {@link TextAnalyticsError}. + * + * @param details about specific errors that led to this reported error. + * @return the {@link TextAnalyticsError} returned by the SDK. + */ + private static List setErrors( + List details) { + List detailsList = new ArrayList<>(); + for (TextAnalyticsError error : details) { + detailsList.add(new com.azure.ai.textanalytics.models.TextAnalyticsError( + ErrorCodeValue.fromString(error.getCode().toString()), + error.getMessage(), + error.getTarget(), error.getDetails() == null ? null : setErrors(error.getDetails()))); + } + return detailsList; + } +} diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/samples/java/com/azure/ai/textanalytics/RecognizePii.java b/sdk/textanalytics/azure-ai-textanalytics/src/samples/java/com/azure/ai/textanalytics/RecognizePii.java index 257da41ea72b..f3a141c8af59 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/samples/java/com/azure/ai/textanalytics/RecognizePii.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/samples/java/com/azure/ai/textanalytics/RecognizePii.java @@ -28,7 +28,7 @@ public static void main(String[] args) { System.out.printf( "Recognized PII Entity: %s, Entity Type: %s, Entity Subtype: %s, Offset: %s, Length: %s, Score: %s.%n", entity.getText(), - entity.getType() , + entity.getType(), entity.getSubtype() == null || entity.getSubtype().isEmpty() ? "N/A" : entity.getSubtype(), entity.getOffset(), entity.getLength(), diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java index f35885407525..326293aa5fbe 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsAsyncClientTest.java @@ -14,7 +14,6 @@ import com.azure.ai.textanalytics.models.TextSentiment; import com.azure.ai.textanalytics.models.TextSentimentClass; import com.azure.core.exception.HttpResponseException; -import com.azure.core.util.Context; import org.junit.jupiter.api.Test; import reactor.test.StepVerifier; @@ -136,7 +135,7 @@ public void detectLanguageFaultyText() { @Test public void detectLanguageDuplicateIdInput() { detectLanguageDuplicateIdRunner((inputs, options) -> { - StepVerifier.create(client.detectBatchLanguagesWithResponse(inputs, options, Context.NONE)) + StepVerifier.create(client.detectBatchLanguagesWithResponse(inputs, options)) .verifyErrorSatisfies(ex -> assertRestException(ex, HttpResponseException.class, 400)); }); } diff --git a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java index d8bfd0841a03..d510d441aa9c 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java +++ b/sdk/textanalytics/azure-ai-textanalytics/src/test/java/com/azure/ai/textanalytics/TextAnalyticsClientTestBase.java @@ -462,6 +462,7 @@ void analyseBatchSentimentShowStatsRunner( new TextDocumentInput("1", "The restaurant had amazing gnocchi. The hotel was dark and unclean.") ); TextAnalyticsRequestOptions options = new TextAnalyticsRequestOptions().setShowStatistics(true); + showStatistics = true; testRunner.accept(textDocumentInputs, options); } @@ -695,6 +696,7 @@ private static void validateLinkedEntityMatches(List expected /** * Helper method to verify the error document. + * * @param expectedError the Error returned from the service. * @param actualError the Error returned from the API. */ @@ -890,7 +892,7 @@ static DocumentResultCollection getExpectedBatchDetectedLa DetectLanguageResult detectLanguageResult2 = new DetectLanguageResult("1", textDocumentStatistics2, null, detectedLanguage2, detectedLanguageList2); DetectLanguageResult detectLanguageResult3 = new DetectLanguageResult("2", textDocumentStatistics3, null, detectedLanguage3, detectedLanguageList3); - TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(3, 0, 3, 3); + TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(3, 3, 0, 3); List detectLanguageResultList = Arrays.asList(detectLanguageResult1, detectLanguageResult2, detectLanguageResult3); return new DocumentResultCollection<>(detectLanguageResultList, MODEL_VERSION, textDocumentBatchStatistics); @@ -910,7 +912,7 @@ static DocumentResultCollection getExpectedBatchNamedEn RecognizeEntitiesResult recognizeEntitiesResult1 = new RecognizeEntitiesResult("0", textDocumentStatistics1, null, namedEntityList1); RecognizeEntitiesResult recognizeEntitiesResult2 = new RecognizeEntitiesResult("1", textDocumentStatistics2, null, namedEntityList2); - TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 0, 2, 2); + TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 2, 0, 2); List recognizeEntitiesResultList = Arrays.asList(recognizeEntitiesResult1, recognizeEntitiesResult2); return new DocumentResultCollection<>(recognizeEntitiesResultList, MODEL_VERSION, textDocumentBatchStatistics); @@ -929,7 +931,7 @@ static DocumentResultCollection getExpectedBatchPiiE RecognizePiiEntitiesResult recognizeEntitiesResult1 = new RecognizePiiEntitiesResult("0", textDocumentStatistics1, null, namedEntityList1); RecognizePiiEntitiesResult recognizeEntitiesResult2 = new RecognizePiiEntitiesResult("1", textDocumentStatistics2, null, namedEntityList2); - TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 0, 2, 2); + TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 2, 0, 2); List recognizeEntitiesResultList = Arrays.asList(recognizeEntitiesResult1, recognizeEntitiesResult2); return new DocumentResultCollection<>(recognizeEntitiesResultList, MODEL_VERSION, textDocumentBatchStatistics); @@ -958,7 +960,7 @@ static DocumentResultCollection getExpectedBatchL RecognizeLinkedEntitiesResult recognizeLinkedEntitiesResult1 = new RecognizeLinkedEntitiesResult("0", textDocumentStatistics1, null, linkedEntityList1); RecognizeLinkedEntitiesResult recognizeLinkedEntitiesResult2 = new RecognizeLinkedEntitiesResult("1", textDocumentStatistics2, null, linkedEntityList2); - TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 0, 2, 2); + TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 2, 0, 2); List recognizeLinkedEntitiesResultList = Arrays.asList(recognizeLinkedEntitiesResult1, recognizeLinkedEntitiesResult2); return new DocumentResultCollection<>(recognizeLinkedEntitiesResultList, MODEL_VERSION, textDocumentBatchStatistics); @@ -974,7 +976,7 @@ static DocumentResultCollection getExpectedBatchKeyPhras ExtractKeyPhraseResult extractKeyPhraseResult1 = new ExtractKeyPhraseResult("0", textDocumentStatistics1, null, keyPhrasesList1); ExtractKeyPhraseResult extractKeyPhraseResult2 = new ExtractKeyPhraseResult("1", textDocumentStatistics2, null, keyPhrasesList2); - TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 0, 2, 2); + TextDocumentBatchStatistics textDocumentBatchStatistics = new TextDocumentBatchStatistics(2, 2, 0, 2); List extractKeyPhraseResultList = Arrays.asList(extractKeyPhraseResult1, extractKeyPhraseResult2); return new DocumentResultCollection<>(extractKeyPhraseResultList, MODEL_VERSION, textDocumentBatchStatistics); @@ -1005,6 +1007,6 @@ static DocumentResultCollection getExpectedBatchTextSent return new DocumentResultCollection<>(Arrays.asList(analyzeSentimentResult1, analyzeSentimentResult2), MODEL_VERSION, - new TextDocumentBatchStatistics(2, 0, 2, 2)); + new TextDocumentBatchStatistics(2, 2, 0, 2)); } }