From ce6a5b83004b0f7eafa5ce3456ae3c7a96716505 Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Thu, 7 Aug 2025 17:49:09 -0400 Subject: [PATCH 01/12] Update Swaggers and regen searchindex --- .../documents/models/VectorFilterMode.java | 7 +++++++ .../azure-search-documents/swagger/README.md | 17 +++-------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/models/VectorFilterMode.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/models/VectorFilterMode.java index a52154fa7a48..9013c2870389 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/models/VectorFilterMode.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/models/VectorFilterMode.java @@ -27,6 +27,13 @@ public final class VectorFilterMode extends ExpandableStringEnum p.name === "speller")["x-ms-enum"].name = "QuerySpellerType"; ``` -### Fix `SearchResult["@search.documentDebugInfo"]` -``` yaml $(tag) == 'searchindex' -directive: - - from: swagger-document - where: $.definitions.SearchResult.properties - transform: > - $["@search.documentDebugInfo"]["$ref"] = $["@search.documentDebugInfo"].items["$ref"]; - delete $["@search.documentDebugInfo"].type; - delete $["@search.documentDebugInfo"].items; -``` - ### Rename `AI Studio` to `AI Foundry` ```yaml directive: From 6c895717314df09f1beae320dcfa3a9ec3fbf7c2 Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:06:32 -0400 Subject: [PATCH 02/12] Regen searchservice --- .../indexes/SearchIndexAsyncClient.java | 224 ++++- .../documents/indexes/SearchIndexClient.java | 197 ++++- .../implementation/KnowledgeSourcesImpl.java | 820 ++++++++++++++++++ .../SearchServiceClientImpl.java | 15 + .../models/AzureBlobKnowledgeSource.java | 178 ++++ .../AzureBlobKnowledgeSourceParameters.java | 350 ++++++++ .../indexes/models/KnowledgeAgent.java | 107 ++- .../KnowledgeAgentOutputConfiguration.java | 194 +++++ ...ledgeAgentOutputConfigurationModality.java | 60 ++ .../KnowledgeAgentOutputOptimization.java | 53 ++ .../models/KnowledgeAgentTargetIndex.java | 193 ----- .../indexes/models/KnowledgeSource.java | 260 ++++++ .../indexes/models/KnowledgeSourceKind.java | 65 ++ .../models/KnowledgeSourceReference.java | 267 ++++++ .../models/ListKnowledgeSourcesResult.java | 91 ++ .../models/SearchIndexKnowledgeSource.java | 178 ++++ .../SearchIndexKnowledgeSourceParameters.java | 127 +++ .../SearchIndexerDataSourceConnection.java | 22 + .../indexes/models/SearchIndexerStatus.java | 34 +- .../indexes/models/WebKnowledgeSource.java | 177 ++++ .../WebKnowledgeSourceAllowedDomain.java | 160 ++++ .../WebKnowledgeSourceBlockedDomain.java | 126 +++ .../models/WebKnowledgeSourceParameters.java | 287 ++++++ .../WebKnowledgeSourceRankingAdjustment.java | 67 ++ .../search/documents/KnowledgeAgentTests.java | 47 +- .../azure-search-documents/swagger/README.md | 39 - 26 files changed, 4034 insertions(+), 304 deletions(-) create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSource.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSourceParameters.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfiguration.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfigurationModality.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentTargetIndex.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceReference.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeSourcesResult.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSource.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSourceParameters.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSource.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java index c3f380552e4d..587200c96279 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java @@ -27,6 +27,7 @@ import com.azure.search.documents.indexes.models.FieldBuilderOptions; import com.azure.search.documents.indexes.models.IndexStatisticsSummary; import com.azure.search.documents.indexes.models.KnowledgeAgent; +import com.azure.search.documents.indexes.models.KnowledgeSource; import com.azure.search.documents.indexes.models.SearchField; import com.azure.search.documents.indexes.models.SearchIndex; import com.azure.search.documents.indexes.models.SearchIndexStatistics; @@ -1270,7 +1271,7 @@ PagedFlux getIndexStatsSummary(Context context) { /** * Creates a new agent. - * + * * @param knowledgeAgent The definition of the agent to create. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1279,12 +1280,12 @@ PagedFlux getIndexStatsSummary(Context context) { */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono createKnowledgeAgent(KnowledgeAgent knowledgeAgent) { - return createKnowledgeAgentWithResponse(knowledgeAgent, Context.NONE).map(Response::getValue); + return createKnowledgeAgentWithResponse(knowledgeAgent).map(Response::getValue); } /** * Creates a new agent. - * + * * @param knowledgeAgent The definition of the agent to create. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1308,7 +1309,7 @@ Mono> createKnowledgeAgentWithResponse(KnowledgeAgent k /** * Creates a new agent or updates an agent if it already exists. - * + * * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server @@ -1323,13 +1324,13 @@ Mono> createKnowledgeAgentWithResponse(KnowledgeAgent k @ServiceMethod(returns = ReturnType.SINGLE) public Mono createOrUpdateKnowledgeAgent(String agentName, KnowledgeAgent knowledgeAgent, String ifMatch, String ifNoneMatch) { - return createOrUpdateKnowledgeAgentWithResponse(agentName, knowledgeAgent, ifMatch, ifNoneMatch, Context.NONE) + return createOrUpdateKnowledgeAgentWithResponse(agentName, knowledgeAgent, ifMatch, ifNoneMatch) .map(Response::getValue); } /** * Creates a new agent or updates an agent if it already exists. - * + * * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server @@ -1361,7 +1362,7 @@ Mono> createOrUpdateKnowledgeAgentWithResponse(String a /** * Retrieves an agent definition. - * + * * @param agentName The name of the agent to retrieve. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1370,13 +1371,12 @@ Mono> createOrUpdateKnowledgeAgentWithResponse(String a */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono getKnowledgeAgent(String agentName) { - return getKnowledgeAgentWithResponse(agentName, Context.NONE).map(Response::getValue); - + return getKnowledgeAgentWithResponse(agentName).map(Response::getValue); } /** * Retrieves an agent definition. - * + * * @param agentName The name of the agent to retrieve. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1400,7 +1400,7 @@ Mono> getKnowledgeAgentWithResponse(String agentName, C /** * Lists all agents available for a search service. - * + * * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. @@ -1418,7 +1418,7 @@ public PagedFlux listKnowledgeAgents() { /** * Deletes an existing agent. - * + * * @param agentName The name of the agent to delete. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1431,13 +1431,12 @@ public PagedFlux listKnowledgeAgents() { */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono deleteKnowledgeAgent(String agentName, String ifMatch, String ifNoneMatch) { - return deleteKnowledgeAgentWithResponse(agentName, ifMatch, ifNoneMatch, Context.NONE) - .flatMap(FluxUtil::toMono); + return deleteKnowledgeAgentWithResponse(agentName, ifMatch, ifNoneMatch).flatMap(FluxUtil::toMono); } /** * Deletes an existing agent. - * + * * @param agentName The name of the agent to delete. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1462,6 +1461,201 @@ Mono> deleteKnowledgeAgentWithResponse(String agentName, String i } catch (RuntimeException ex) { return monoError(LOGGER, ex); } + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that will produce the created knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createKnowledgeSource(KnowledgeSource knowledgeSource) { + return createKnowledgeSourceWithResponse(knowledgeSource).map(Response::getValue); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that will produce a {@link Response} containing the created knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource) { + return withContext(context -> createKnowledgeSourceWithResponse(knowledgeSource, context)); + } + + Mono> createKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, + Context context) { + try { + return restClient.getKnowledgeSources() + .createWithResponseAsync(knowledgeSource, null, context) + .onErrorMap(MappingUtils::exceptionMapper); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + + /** + * Creates or updates a knowledge source. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that will produce the created or updated knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createOrUpdateKnowledgeSource(String sourceName, KnowledgeSource knowledgeSource, + String ifMatch, String ifNoneMatch) { + return createOrUpdateKnowledgeSourceWithResponse(sourceName, knowledgeSource, ifMatch, ifNoneMatch) + .map(Response::getValue); + } + + /** + * Creates or updates a knowledge source. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that produces a {@link Response} containing the created or updated knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createOrUpdateKnowledgeSourceWithResponse(String sourceName, + KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch) { + return withContext(context -> createOrUpdateKnowledgeSourceWithResponse(sourceName, knowledgeSource, ifMatch, + ifNoneMatch, context)); + } + + Mono> createOrUpdateKnowledgeSourceWithResponse(String sourceName, + KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch, Context context) { + try { + return restClient.getKnowledgeSources() + .createOrUpdateWithResponseAsync(sourceName, knowledgeSource, ifMatch, null, null, context) + .onErrorMap(MappingUtils::exceptionMapper); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + + /** + * Retrieves a knowledge source. + * + * @param sourceName The name of the knowledge source to retrieve. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that will produce the retrieved knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getKnowledgeSource(String sourceName) { + return getKnowledgeSourceWithResponse(sourceName).map(Response::getValue); + } + + /** + * Retrieves a knowledge source. + * + * @param sourceName The name of the knowledge source to retrieve. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that will produce a {@link Response} containing the retrieved knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getKnowledgeSourceWithResponse(String sourceName) { + return withContext(context -> getKnowledgeSourceWithResponse(sourceName, context)); + } + + Mono> getKnowledgeSourceWithResponse(String sourceName, Context context) { + try { + return restClient.getKnowledgeSources() + .getWithResponseAsync(sourceName, null, context) + .onErrorMap(MappingUtils::exceptionMapper); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + + /** + * Lists all knowledge sources available for a search service. + * + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link PagedFlux} of knowledge source. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listKnowledgeSources() { + try { + return restClient.getKnowledgeSources().listAsync(null, Context.NONE); + } catch (RuntimeException ex) { + RuntimeException mappedException = (RuntimeException) MappingUtils.exceptionMapper(ex); + return pagedFluxError(LOGGER, mappedException); + } + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that completes successfully if the knowledge source was deleted. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono deleteKnowledgeSource(String sourceName, String ifMatch, String ifNoneMatch) { + return deleteKnowledgeAgentWithResponse(sourceName, ifMatch, ifNoneMatch).flatMap(FluxUtil::toMono); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that produces a {@link Response} if the knowledge source was deleted. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteKnowledgeSourceWithResponse(String sourceName, String ifMatch, + String ifNoneMatch) { + return withContext(context -> deleteKnowledgeSourceWithResponse(sourceName, ifMatch, ifNoneMatch, context)); + } + Mono> deleteKnowledgeSourceWithResponse(String sourceName, String ifMatch, String ifNoneMatch, + Context context) { + try { + return restClient.getKnowledgeSources() + .deleteWithResponseAsync(sourceName, ifMatch, ifNoneMatch, null, context) + .onErrorMap(MappingUtils::exceptionMapper); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java index 79ab904d9f58..aa3daa557cdd 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java @@ -25,6 +25,7 @@ import com.azure.search.documents.indexes.models.FieldBuilderOptions; import com.azure.search.documents.indexes.models.IndexStatisticsSummary; import com.azure.search.documents.indexes.models.KnowledgeAgent; +import com.azure.search.documents.indexes.models.KnowledgeSource; import com.azure.search.documents.indexes.models.LexicalAnalyzerName; import com.azure.search.documents.indexes.models.LexicalTokenizerName; import com.azure.search.documents.indexes.models.SearchField; @@ -1312,7 +1313,7 @@ public static List buildSearchFields(Class model, FieldBuilderOp /** * Creates a new agent. - * + * * @param knowledgeAgent The definition of the agent to create. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1322,12 +1323,11 @@ public static List buildSearchFields(Class model, FieldBuilderOp @ServiceMethod(returns = ReturnType.SINGLE) public KnowledgeAgent createKnowledgeAgent(KnowledgeAgent knowledgeAgent) { return createKnowledgeAgentWithResponse(knowledgeAgent, Context.NONE).getValue(); - } /** * Creates a new agent. - * + * * @param knowledgeAgent The definition of the agent to create. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. @@ -1339,12 +1339,11 @@ public KnowledgeAgent createKnowledgeAgent(KnowledgeAgent knowledgeAgent) { public Response createKnowledgeAgentWithResponse(KnowledgeAgent knowledgeAgent, Context context) { return Utility.executeRestCallWithExceptionHandling( () -> restClient.getKnowledgeAgents().createWithResponse(knowledgeAgent, null, context), LOGGER); - } /** * Creates a new agent or updates an agent if it already exists. - * + * * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server @@ -1365,7 +1364,7 @@ public KnowledgeAgent createOrUpdateKnowledgeAgent(String agentName, KnowledgeAg /** * Creates a new agent or updates an agent if it already exists. - * + * * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server @@ -1390,7 +1389,7 @@ public Response createOrUpdateKnowledgeAgentWithResponse(String /** * Retrieves an agent definition. - * + * * @param agentName The name of the agent to retrieve. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1405,7 +1404,7 @@ public KnowledgeAgent getKnowledgeAgent(String agentName) { /** * Retrieves an agent definition. - * + * * @param agentName The name of the agent to retrieve. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. @@ -1421,7 +1420,7 @@ public Response getKnowledgeAgentWithResponse(String agentName, /** * Lists all agents available for a search service. - * + * * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. @@ -1434,7 +1433,7 @@ public PagedIterable listKnowledgeAgents() { /** * Lists all agents available for a search service. - * + * * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1449,7 +1448,7 @@ public PagedIterable listKnowledgeAgents(Context context) { /** * Deletes an existing agent. - * + * * @param agentName The name of the agent to delete. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1466,7 +1465,7 @@ public void deleteKnowledgeAgent(String agentName, String ifMatch, String ifNone /** * Deletes an existing agent. - * + * * @param agentName The name of the agent to delete. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1484,6 +1483,180 @@ public Response deleteKnowledgeAgentWithResponse(String agentName, String return Utility.executeRestCallWithExceptionHandling( () -> restClient.getKnowledgeAgents().deleteWithResponse(agentName, ifMatch, ifNoneMatch, null, context), LOGGER); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return The created knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public KnowledgeSource createKnowledgeSource(KnowledgeSource knowledgeSource) { + return createKnowledgeSourceWithResponse(knowledgeSource, Context.NONE).getValue(); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Response} containing the created knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response createKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, + Context context) { + return Utility.executeRestCallWithExceptionHandling( + () -> restClient.getKnowledgeSources().createWithResponse(knowledgeSource, null, context), LOGGER); + } + /** + * Creates or updates a knowledge source. + * + * @param sourceName The name of the source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return The created or updated knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public KnowledgeSource createOrUpdateKnowledgeSource(String sourceName, KnowledgeSource knowledgeSource, + String ifMatch, String ifNoneMatch) { + return createOrUpdateKnowledgeSourceWithResponse(sourceName, knowledgeSource, ifMatch, ifNoneMatch, + Context.NONE).getValue(); + } + + /** + * Creates or updates a knowledge source. + * + * @param sourceName The name of the source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Response} containing the created or updated knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response createOrUpdateKnowledgeSourceWithResponse(String sourceName, + KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch, Context context) { + return Utility + .executeRestCallWithExceptionHandling( + () -> restClient.getKnowledgeSources() + .createOrUpdateWithResponse(sourceName, knowledgeSource, ifMatch, ifNoneMatch, null, context), + LOGGER); + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return The retrieved knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public KnowledgeSource getKnowledgeSource(String sourceName) { + return getKnowledgeSourceWithResponse(sourceName, Context.NONE).getValue(); + + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Response} containing the retrieved knowledge source. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getKnowledgeSourceWithResponse(String sourceName, Context context) { + return Utility.executeRestCallWithExceptionHandling( + () -> restClient.getKnowledgeSources().getWithResponse(sourceName, null, context), LOGGER); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link PagedIterable} of knowledge sources. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listKnowledgeSources() { + return listKnowledgeSources(Context.NONE); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link PagedIterable} of knowledge sources. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listKnowledgeSources(Context context) { + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getKnowledgeSources().list(null, context), + LOGGER); + } + + /** + * Deletes an existing knowledge agent. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public void deleteKnowledgeSource(String sourceName, String ifMatch, String ifNoneMatch) { + deleteKnowledgeSourceWithResponse(sourceName, ifMatch, ifNoneMatch, Context.NONE).getValue(); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Response} indicating deletion completed. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response deleteKnowledgeSourceWithResponse(String sourceName, String ifMatch, String ifNoneMatch, + Context context) { + return Utility.executeRestCallWithExceptionHandling( + () -> restClient.getKnowledgeSources().deleteWithResponse(sourceName, ifMatch, ifNoneMatch, null, context), + LOGGER); } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java new file mode 100644 index 000000000000..e48ce3545d81 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java @@ -0,0 +1,820 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.implementation; + +import com.azure.core.annotation.BodyParam; +import com.azure.core.annotation.Delete; +import com.azure.core.annotation.ExpectedResponses; +import com.azure.core.annotation.Get; +import com.azure.core.annotation.HeaderParam; +import com.azure.core.annotation.Host; +import com.azure.core.annotation.HostParam; +import com.azure.core.annotation.PathParam; +import com.azure.core.annotation.Post; +import com.azure.core.annotation.Put; +import com.azure.core.annotation.QueryParam; +import com.azure.core.annotation.ReturnType; +import com.azure.core.annotation.ServiceInterface; +import com.azure.core.annotation.ServiceMethod; +import com.azure.core.annotation.UnexpectedResponseExceptionType; +import com.azure.core.http.rest.PagedFlux; +import com.azure.core.http.rest.PagedIterable; +import com.azure.core.http.rest.PagedResponse; +import com.azure.core.http.rest.PagedResponseBase; +import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.RestProxy; +import com.azure.core.util.Context; +import com.azure.core.util.FluxUtil; +import com.azure.search.documents.indexes.implementation.models.ErrorResponseException; +import com.azure.search.documents.indexes.implementation.models.RequestOptions; +import com.azure.search.documents.indexes.models.KnowledgeSource; +import com.azure.search.documents.indexes.models.ListKnowledgeSourcesResult; +import java.util.UUID; +import reactor.core.publisher.Mono; + +/** + * An instance of this class provides access to all the operations defined in KnowledgeSources. + */ +public final class KnowledgeSourcesImpl { + /** + * The proxy service used to perform REST calls. + */ + private final KnowledgeSourcesService service; + + /** + * The service client containing this operation class. + */ + private final SearchServiceClientImpl client; + + /** + * Initializes an instance of KnowledgeSourcesImpl. + * + * @param client the instance of the service client containing this operation class. + */ + KnowledgeSourcesImpl(SearchServiceClientImpl client) { + this.service + = RestProxy.create(KnowledgeSourcesService.class, client.getHttpPipeline(), client.getSerializerAdapter()); + this.client = client; + } + + /** + * The interface defining all the services for SearchServiceClientKnowledgeSources to be used by the proxy service + * to perform REST calls. + */ + @Host("{endpoint}") + @ServiceInterface(name = "SearchServiceClientKnowledgeSources") + public interface KnowledgeSourcesService { + @Put("/knowledgesources('{sourceName}')") + @ExpectedResponses({ 200, 201 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Mono> createOrUpdate(@HostParam("endpoint") String endpoint, + @PathParam("sourceName") String sourceName, @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch, + @HeaderParam("Prefer") String prefer, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, @BodyParam("application/json") KnowledgeSource knowledgeSource, + Context context); + + @Put("/knowledgesources('{sourceName}')") + @ExpectedResponses({ 200, 201 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Response createOrUpdateSync(@HostParam("endpoint") String endpoint, + @PathParam("sourceName") String sourceName, @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch, + @HeaderParam("Prefer") String prefer, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, @BodyParam("application/json") KnowledgeSource knowledgeSource, + Context context); + + @Delete("/knowledgesources('{sourceName}')") + @ExpectedResponses({ 204, 404 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Mono> delete(@HostParam("endpoint") String endpoint, @PathParam("sourceName") String sourceName, + @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, @HeaderParam("If-Match") String ifMatch, + @HeaderParam("If-None-Match") String ifNoneMatch, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, Context context); + + @Delete("/knowledgesources('{sourceName}')") + @ExpectedResponses({ 204, 404 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Response deleteSync(@HostParam("endpoint") String endpoint, @PathParam("sourceName") String sourceName, + @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, @HeaderParam("If-Match") String ifMatch, + @HeaderParam("If-None-Match") String ifNoneMatch, @QueryParam("api-version") String apiVersion, + @HeaderParam("Accept") String accept, Context context); + + @Get("/knowledgesources('{sourceName}')") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Mono> get(@HostParam("endpoint") String endpoint, + @PathParam("sourceName") String sourceName, @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, Context context); + + @Get("/knowledgesources('{sourceName}')") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Response getSync(@HostParam("endpoint") String endpoint, + @PathParam("sourceName") String sourceName, @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, Context context); + + @Get("/knowledgesources") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Mono> list(@HostParam("endpoint") String endpoint, + @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, Context context); + + @Get("/knowledgesources") + @ExpectedResponses({ 200 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Response listSync(@HostParam("endpoint") String endpoint, + @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, Context context); + + @Post("/knowledgesources") + @ExpectedResponses({ 201 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Mono> create(@HostParam("endpoint") String endpoint, + @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + @BodyParam("application/json") KnowledgeSource knowledgeSource, Context context); + + @Post("/knowledgesources") + @ExpectedResponses({ 201 }) + @UnexpectedResponseExceptionType(ErrorResponseException.class) + Response createSync(@HostParam("endpoint") String endpoint, + @HeaderParam("x-ms-client-request-id") UUID xMsClientRequestId, + @QueryParam("api-version") String apiVersion, @HeaderParam("Accept") String accept, + @BodyParam("application/json") KnowledgeSource knowledgeSource, Context context); + } + + /** + * Creates a new knowledge source or updates an knowledge source if it already exists. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response} on successful completion of + * {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createOrUpdateWithResponseAsync(String sourceName, + KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch, RequestOptions requestOptions) { + return FluxUtil.withContext(context -> createOrUpdateWithResponseAsync(sourceName, knowledgeSource, ifMatch, + ifNoneMatch, requestOptions, context)); + } + + /** + * Creates a new knowledge source or updates an knowledge source if it already exists. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response} on successful completion of + * {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createOrUpdateWithResponseAsync(String sourceName, + KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch, RequestOptions requestOptions, + Context context) { + final String prefer = "return=representation"; + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.createOrUpdate(this.client.getEndpoint(), sourceName, xMsClientRequestId, ifMatch, ifNoneMatch, + prefer, this.client.getApiVersion(), accept, knowledgeSource, context); + } + + /** + * Creates a new knowledge source or updates an knowledge source if it already exists. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createOrUpdateAsync(String sourceName, KnowledgeSource knowledgeSource, String ifMatch, + String ifNoneMatch, RequestOptions requestOptions) { + return createOrUpdateWithResponseAsync(sourceName, knowledgeSource, ifMatch, ifNoneMatch, requestOptions) + .flatMap(res -> Mono.justOrEmpty(res.getValue())); + } + + /** + * Creates a new knowledge source or updates an knowledge source if it already exists. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createOrUpdateAsync(String sourceName, KnowledgeSource knowledgeSource, String ifMatch, + String ifNoneMatch, RequestOptions requestOptions, Context context) { + return createOrUpdateWithResponseAsync(sourceName, knowledgeSource, ifMatch, ifNoneMatch, requestOptions, + context).flatMap(res -> Mono.justOrEmpty(res.getValue())); + } + + /** + * Creates a new knowledge source or updates an knowledge source if it already exists. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response createOrUpdateWithResponse(String sourceName, KnowledgeSource knowledgeSource, + String ifMatch, String ifNoneMatch, RequestOptions requestOptions, Context context) { + final String prefer = "return=representation"; + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.createOrUpdateSync(this.client.getEndpoint(), sourceName, xMsClientRequestId, ifMatch, + ifNoneMatch, prefer, this.client.getApiVersion(), accept, knowledgeSource, context); + } + + /** + * Creates a new knowledge source or updates an knowledge source if it already exists. + * + * @param sourceName The name of the knowledge source to create or update. + * @param knowledgeSource The definition of the knowledge source to create or update. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public KnowledgeSource createOrUpdate(String sourceName, KnowledgeSource knowledgeSource, String ifMatch, + String ifNoneMatch, RequestOptions requestOptions) { + return createOrUpdateWithResponse(sourceName, knowledgeSource, ifMatch, ifNoneMatch, requestOptions, + Context.NONE).getValue(); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteWithResponseAsync(String sourceName, String ifMatch, String ifNoneMatch, + RequestOptions requestOptions) { + return FluxUtil + .withContext(context -> deleteWithResponseAsync(sourceName, ifMatch, ifNoneMatch, requestOptions, context)); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link Response} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteWithResponseAsync(String sourceName, String ifMatch, String ifNoneMatch, + RequestOptions requestOptions, Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.delete(this.client.getEndpoint(), sourceName, xMsClientRequestId, ifMatch, ifNoneMatch, + this.client.getApiVersion(), accept, context); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that completes when a successful response is received. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono deleteAsync(String sourceName, String ifMatch, String ifNoneMatch, + RequestOptions requestOptions) { + return deleteWithResponseAsync(sourceName, ifMatch, ifNoneMatch, requestOptions) + .flatMap(ignored -> Mono.empty()); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return A {@link Mono} that completes when a successful response is received. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono deleteAsync(String sourceName, String ifMatch, String ifNoneMatch, RequestOptions requestOptions, + Context context) { + return deleteWithResponseAsync(sourceName, ifMatch, ifNoneMatch, requestOptions, context) + .flatMap(ignored -> Mono.empty()); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response deleteWithResponse(String sourceName, String ifMatch, String ifNoneMatch, + RequestOptions requestOptions, Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.deleteSync(this.client.getEndpoint(), sourceName, xMsClientRequestId, ifMatch, ifNoneMatch, + this.client.getApiVersion(), accept, context); + } + + /** + * Deletes an existing knowledge source. + * + * @param sourceName The name of the knowledge source to delete. + * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server + * matches this value. + * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the + * server does not match this value. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public void delete(String sourceName, String ifMatch, String ifNoneMatch, RequestOptions requestOptions) { + deleteWithResponse(sourceName, ifMatch, ifNoneMatch, requestOptions, Context.NONE); + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response} on successful completion of + * {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getWithResponseAsync(String sourceName, RequestOptions requestOptions) { + return FluxUtil.withContext(context -> getWithResponseAsync(sourceName, requestOptions, context)); + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response} on successful completion of + * {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getWithResponseAsync(String sourceName, RequestOptions requestOptions, + Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.get(this.client.getEndpoint(), sourceName, xMsClientRequestId, this.client.getApiVersion(), + accept, context); + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getAsync(String sourceName, RequestOptions requestOptions) { + return getWithResponseAsync(sourceName, requestOptions).flatMap(res -> Mono.justOrEmpty(res.getValue())); + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getAsync(String sourceName, RequestOptions requestOptions, Context context) { + return getWithResponseAsync(sourceName, requestOptions, context) + .flatMap(res -> Mono.justOrEmpty(res.getValue())); + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getWithResponse(String sourceName, RequestOptions requestOptions, + Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.getSync(this.client.getEndpoint(), sourceName, xMsClientRequestId, this.client.getApiVersion(), + accept, context); + } + + /** + * Retrieves a knowledge source definition. + * + * @param sourceName The name of the knowledge source to retrieve. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public KnowledgeSource get(String sourceName, RequestOptions requestOptions) { + return getWithResponse(sourceName, requestOptions, Context.NONE).getValue(); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response body along with {@link PagedResponse} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> listSinglePageAsync(RequestOptions requestOptions) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return FluxUtil + .withContext(context -> service.list(this.client.getEndpoint(), xMsClientRequestId, + this.client.getApiVersion(), accept, context)) + .map(res -> new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + res.getValue().getKnowledgeSources(), null, null)); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response body along with {@link PagedResponse} on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> listSinglePageAsync(RequestOptions requestOptions, Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.list(this.client.getEndpoint(), xMsClientRequestId, this.client.getApiVersion(), accept, context) + .map(res -> new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + res.getValue().getKnowledgeSources(), null, null)); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the paginated response with {@link PagedFlux}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAsync(RequestOptions requestOptions) { + return new PagedFlux<>(() -> listSinglePageAsync(requestOptions)); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the paginated response with {@link PagedFlux}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listAsync(RequestOptions requestOptions, Context context) { + return new PagedFlux<>(() -> listSinglePageAsync(requestOptions, context)); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response body along with {@link PagedResponse}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public PagedResponse listSinglePage(RequestOptions requestOptions) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + Response res = service.listSync(this.client.getEndpoint(), xMsClientRequestId, + this.client.getApiVersion(), accept, Context.NONE); + return new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + res.getValue().getKnowledgeSources(), null, null); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the response body along with {@link PagedResponse}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public PagedResponse listSinglePage(RequestOptions requestOptions, Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + Response res = service.listSync(this.client.getEndpoint(), xMsClientRequestId, + this.client.getApiVersion(), accept, context); + return new PagedResponseBase<>(res.getRequest(), res.getStatusCode(), res.getHeaders(), + res.getValue().getKnowledgeSources(), null, null); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the paginated response with {@link PagedIterable}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable list(RequestOptions requestOptions) { + return new PagedIterable<>(() -> listSinglePage(requestOptions)); + } + + /** + * Lists all knowledge sources available for a search service. + * + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return the paginated response with {@link PagedIterable}. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable list(RequestOptions requestOptions, Context context) { + return new PagedIterable<>(() -> listSinglePage(requestOptions, context)); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response} on successful completion of + * {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createWithResponseAsync(KnowledgeSource knowledgeSource, + RequestOptions requestOptions) { + return FluxUtil.withContext(context -> createWithResponseAsync(knowledgeSource, requestOptions, context)); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response} on successful completion of + * {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createWithResponseAsync(KnowledgeSource knowledgeSource, + RequestOptions requestOptions, Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.create(this.client.getEndpoint(), xMsClientRequestId, this.client.getApiVersion(), accept, + knowledgeSource, context); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createAsync(KnowledgeSource knowledgeSource, RequestOptions requestOptions) { + return createWithResponseAsync(knowledgeSource, requestOptions) + .flatMap(res -> Mono.justOrEmpty(res.getValue())); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition on successful completion of {@link Mono}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono createAsync(KnowledgeSource knowledgeSource, RequestOptions requestOptions, + Context context) { + return createWithResponseAsync(knowledgeSource, requestOptions, context) + .flatMap(res -> Mono.justOrEmpty(res.getValue())); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @param requestOptions Parameter group. + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition along with {@link Response}. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response createWithResponse(KnowledgeSource knowledgeSource, RequestOptions requestOptions, + Context context) { + final String accept = "application/json; odata.metadata=minimal"; + UUID xMsClientRequestIdInternal = null; + if (requestOptions != null) { + xMsClientRequestIdInternal = requestOptions.getXMsClientRequestId(); + } + UUID xMsClientRequestId = xMsClientRequestIdInternal; + return service.createSync(this.client.getEndpoint(), xMsClientRequestId, this.client.getApiVersion(), accept, + knowledgeSource, context); + } + + /** + * Creates a new knowledge source. + * + * @param knowledgeSource The definition of the knowledge source to create. + * @param requestOptions Parameter group. + * @throws IllegalArgumentException thrown if parameters fail the validation. + * @throws ErrorResponseException thrown if the request is rejected by server. + * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. + * @return represents a knowledge source definition. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public KnowledgeSource create(KnowledgeSource knowledgeSource, RequestOptions requestOptions) { + return createWithResponse(knowledgeSource, requestOptions, Context.NONE).getValue(); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java index 9f11a55454c5..b76f2121161e 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java @@ -117,6 +117,20 @@ public KnowledgeAgentsImpl getKnowledgeAgents() { return this.knowledgeAgents; } + /** + * The KnowledgeSourcesImpl object to access its operations. + */ + private final KnowledgeSourcesImpl knowledgeSources; + + /** + * Gets the KnowledgeSourcesImpl object to access its operations. + * + * @return the KnowledgeSourcesImpl object. + */ + public KnowledgeSourcesImpl getKnowledgeSources() { + return this.knowledgeSources; + } + /** * The DataSourcesImpl object to access its operations. */ @@ -238,6 +252,7 @@ public SearchServiceClientImpl(HttpPipeline httpPipeline, SerializerAdapter seri this.endpoint = endpoint; this.apiVersion = apiVersion; this.knowledgeAgents = new KnowledgeAgentsImpl(this); + this.knowledgeSources = new KnowledgeSourcesImpl(this); this.dataSources = new DataSourcesImpl(this); this.indexers = new IndexersImpl(this); this.skillsets = new SkillsetsImpl(this); diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSource.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSource.java new file mode 100644 index 000000000000..c8ff531c0022 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSource.java @@ -0,0 +1,178 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Configuration for Azure Blob Storage knowledge source. + */ +@Fluent +public final class AzureBlobKnowledgeSource extends KnowledgeSource { + /* + * The type of the knowledge source. + */ + @Generated + private KnowledgeSourceKind kind = KnowledgeSourceKind.AZURE_BLOB; + + /* + * The type of the knowledge source. + */ + @Generated + private final AzureBlobKnowledgeSourceParameters azureBlobParameters; + + /** + * Creates an instance of AzureBlobKnowledgeSource class. + * + * @param name the name value to set. + * @param azureBlobParameters the azureBlobParameters value to set. + */ + @Generated + public AzureBlobKnowledgeSource(String name, AzureBlobKnowledgeSourceParameters azureBlobParameters) { + super(name); + this.azureBlobParameters = azureBlobParameters; + } + + /** + * Get the kind property: The type of the knowledge source. + * + * @return the kind value. + */ + @Generated + @Override + public KnowledgeSourceKind getKind() { + return this.kind; + } + + /** + * Get the azureBlobParameters property: The type of the knowledge source. + * + * @return the azureBlobParameters value. + */ + @Generated + public AzureBlobKnowledgeSourceParameters getAzureBlobParameters() { + return this.azureBlobParameters; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public AzureBlobKnowledgeSource setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public AzureBlobKnowledgeSource setETag(String eTag) { + super.setETag(eTag); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public AzureBlobKnowledgeSource setEncryptionKey(SearchResourceEncryptionKey encryptionKey) { + super.setEncryptionKey(encryptionKey); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("name", getName()); + jsonWriter.writeStringField("description", getDescription()); + jsonWriter.writeStringField("@odata.etag", getETag()); + jsonWriter.writeJsonField("encryptionKey", getEncryptionKey()); + jsonWriter.writeJsonField("azureBlobParameters", this.azureBlobParameters); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of AzureBlobKnowledgeSource from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of AzureBlobKnowledgeSource if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the AzureBlobKnowledgeSource. + */ + @Generated + public static AzureBlobKnowledgeSource fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean nameFound = false; + String name = null; + String description = null; + String eTag = null; + SearchResourceEncryptionKey encryptionKey = null; + boolean azureBlobParametersFound = false; + AzureBlobKnowledgeSourceParameters azureBlobParameters = null; + KnowledgeSourceKind kind = KnowledgeSourceKind.AZURE_BLOB; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("name".equals(fieldName)) { + name = reader.getString(); + nameFound = true; + } else if ("description".equals(fieldName)) { + description = reader.getString(); + } else if ("@odata.etag".equals(fieldName)) { + eTag = reader.getString(); + } else if ("encryptionKey".equals(fieldName)) { + encryptionKey = SearchResourceEncryptionKey.fromJson(reader); + } else if ("azureBlobParameters".equals(fieldName)) { + azureBlobParameters = AzureBlobKnowledgeSourceParameters.fromJson(reader); + azureBlobParametersFound = true; + } else if ("kind".equals(fieldName)) { + kind = KnowledgeSourceKind.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + if (nameFound && azureBlobParametersFound) { + AzureBlobKnowledgeSource deserializedAzureBlobKnowledgeSource + = new AzureBlobKnowledgeSource(name, azureBlobParameters); + deserializedAzureBlobKnowledgeSource.setDescription(description); + deserializedAzureBlobKnowledgeSource.setETag(eTag); + deserializedAzureBlobKnowledgeSource.setEncryptionKey(encryptionKey); + deserializedAzureBlobKnowledgeSource.kind = kind; + + return deserializedAzureBlobKnowledgeSource; + } + List missingProperties = new ArrayList<>(); + if (!nameFound) { + missingProperties.add("name"); + } + if (!azureBlobParametersFound) { + missingProperties.add("azureBlobParameters"); + } + + throw new IllegalStateException( + "Missing required property/properties: " + String.join(", ", missingProperties)); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSourceParameters.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSourceParameters.java new file mode 100644 index 000000000000..e93b99da8995 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/AzureBlobKnowledgeSourceParameters.java @@ -0,0 +1,350 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Parameters for Azure Blob Storage knowledge source. + */ +@Fluent +public final class AzureBlobKnowledgeSourceParameters implements JsonSerializable { + /* + * An explicit identity to use for this knowledge source. + */ + @Generated + private SearchIndexerDataIdentity identity; + + /* + * Key-based connection string or the ResourceId format if using a managed identity. + */ + @Generated + private final String connectionString; + + /* + * The name of the blob storage container. + */ + @Generated + private final String containerName; + + /* + * Optional folder path within the container. + */ + @Generated + private String folderPath; + + /* + * Optional vectorizer configuration for vectorizing content. + */ + @Generated + private VectorSearchVectorizer embeddingModel; + + /* + * Optional chat completion model for image verbalization or context extraction. + */ + @Generated + private KnowledgeAgentModel chatCompletionModel; + + /* + * Optional schedule for data ingestion. + */ + @Generated + private IndexingSchedule ingestionSchedule; + + /* + * Resources created by the knowledge source. + */ + @Generated + private Map createdResources; + + /* + * Indicates whether image verbalization should be disabled. + */ + @Generated + private Boolean disableImageVerbalization; + + /** + * Creates an instance of AzureBlobKnowledgeSourceParameters class. + * + * @param connectionString the connectionString value to set. + * @param containerName the containerName value to set. + */ + @Generated + public AzureBlobKnowledgeSourceParameters(String connectionString, String containerName) { + this.connectionString = connectionString; + this.containerName = containerName; + } + + /** + * Get the identity property: An explicit identity to use for this knowledge source. + * + * @return the identity value. + */ + @Generated + public SearchIndexerDataIdentity getIdentity() { + return this.identity; + } + + /** + * Set the identity property: An explicit identity to use for this knowledge source. + * + * @param identity the identity value to set. + * @return the AzureBlobKnowledgeSourceParameters object itself. + */ + @Generated + public AzureBlobKnowledgeSourceParameters setIdentity(SearchIndexerDataIdentity identity) { + this.identity = identity; + return this; + } + + /** + * Get the connectionString property: Key-based connection string or the ResourceId format if using a managed + * identity. + * + * @return the connectionString value. + */ + @Generated + public String getConnectionString() { + return this.connectionString; + } + + /** + * Get the containerName property: The name of the blob storage container. + * + * @return the containerName value. + */ + @Generated + public String getContainerName() { + return this.containerName; + } + + /** + * Get the folderPath property: Optional folder path within the container. + * + * @return the folderPath value. + */ + @Generated + public String getFolderPath() { + return this.folderPath; + } + + /** + * Set the folderPath property: Optional folder path within the container. + * + * @param folderPath the folderPath value to set. + * @return the AzureBlobKnowledgeSourceParameters object itself. + */ + @Generated + public AzureBlobKnowledgeSourceParameters setFolderPath(String folderPath) { + this.folderPath = folderPath; + return this; + } + + /** + * Get the embeddingModel property: Optional vectorizer configuration for vectorizing content. + * + * @return the embeddingModel value. + */ + @Generated + public VectorSearchVectorizer getEmbeddingModel() { + return this.embeddingModel; + } + + /** + * Set the embeddingModel property: Optional vectorizer configuration for vectorizing content. + * + * @param embeddingModel the embeddingModel value to set. + * @return the AzureBlobKnowledgeSourceParameters object itself. + */ + @Generated + public AzureBlobKnowledgeSourceParameters setEmbeddingModel(VectorSearchVectorizer embeddingModel) { + this.embeddingModel = embeddingModel; + return this; + } + + /** + * Get the chatCompletionModel property: Optional chat completion model for image verbalization or context + * extraction. + * + * @return the chatCompletionModel value. + */ + @Generated + public KnowledgeAgentModel getChatCompletionModel() { + return this.chatCompletionModel; + } + + /** + * Set the chatCompletionModel property: Optional chat completion model for image verbalization or context + * extraction. + * + * @param chatCompletionModel the chatCompletionModel value to set. + * @return the AzureBlobKnowledgeSourceParameters object itself. + */ + @Generated + public AzureBlobKnowledgeSourceParameters setChatCompletionModel(KnowledgeAgentModel chatCompletionModel) { + this.chatCompletionModel = chatCompletionModel; + return this; + } + + /** + * Get the ingestionSchedule property: Optional schedule for data ingestion. + * + * @return the ingestionSchedule value. + */ + @Generated + public IndexingSchedule getIngestionSchedule() { + return this.ingestionSchedule; + } + + /** + * Set the ingestionSchedule property: Optional schedule for data ingestion. + * + * @param ingestionSchedule the ingestionSchedule value to set. + * @return the AzureBlobKnowledgeSourceParameters object itself. + */ + @Generated + public AzureBlobKnowledgeSourceParameters setIngestionSchedule(IndexingSchedule ingestionSchedule) { + this.ingestionSchedule = ingestionSchedule; + return this; + } + + /** + * Get the createdResources property: Resources created by the knowledge source. + * + * @return the createdResources value. + */ + @Generated + public Map getCreatedResources() { + return this.createdResources; + } + + /** + * Get the disableImageVerbalization property: Indicates whether image verbalization should be disabled. + * + * @return the disableImageVerbalization value. + */ + @Generated + public Boolean isDisableImageVerbalization() { + return this.disableImageVerbalization; + } + + /** + * Set the disableImageVerbalization property: Indicates whether image verbalization should be disabled. + * + * @param disableImageVerbalization the disableImageVerbalization value to set. + * @return the AzureBlobKnowledgeSourceParameters object itself. + */ + @Generated + public AzureBlobKnowledgeSourceParameters setDisableImageVerbalization(Boolean disableImageVerbalization) { + this.disableImageVerbalization = disableImageVerbalization; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("connectionString", this.connectionString); + jsonWriter.writeStringField("containerName", this.containerName); + jsonWriter.writeJsonField("identity", this.identity); + jsonWriter.writeStringField("folderPath", this.folderPath); + jsonWriter.writeJsonField("embeddingModel", this.embeddingModel); + jsonWriter.writeJsonField("chatCompletionModel", this.chatCompletionModel); + jsonWriter.writeJsonField("ingestionSchedule", this.ingestionSchedule); + jsonWriter.writeBooleanField("disableImageVerbalization", this.disableImageVerbalization); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of AzureBlobKnowledgeSourceParameters from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of AzureBlobKnowledgeSourceParameters if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the AzureBlobKnowledgeSourceParameters. + */ + @Generated + public static AzureBlobKnowledgeSourceParameters fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean connectionStringFound = false; + String connectionString = null; + boolean containerNameFound = false; + String containerName = null; + SearchIndexerDataIdentity identity = null; + String folderPath = null; + VectorSearchVectorizer embeddingModel = null; + KnowledgeAgentModel chatCompletionModel = null; + IndexingSchedule ingestionSchedule = null; + Map createdResources = null; + Boolean disableImageVerbalization = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("connectionString".equals(fieldName)) { + connectionString = reader.getString(); + connectionStringFound = true; + } else if ("containerName".equals(fieldName)) { + containerName = reader.getString(); + containerNameFound = true; + } else if ("identity".equals(fieldName)) { + identity = SearchIndexerDataIdentity.fromJson(reader); + } else if ("folderPath".equals(fieldName)) { + folderPath = reader.getString(); + } else if ("embeddingModel".equals(fieldName)) { + embeddingModel = VectorSearchVectorizer.fromJson(reader); + } else if ("chatCompletionModel".equals(fieldName)) { + chatCompletionModel = KnowledgeAgentModel.fromJson(reader); + } else if ("ingestionSchedule".equals(fieldName)) { + ingestionSchedule = IndexingSchedule.fromJson(reader); + } else if ("createdResources".equals(fieldName)) { + createdResources = reader.readMap(reader1 -> reader1.getString()); + } else if ("disableImageVerbalization".equals(fieldName)) { + disableImageVerbalization = reader.getNullable(JsonReader::getBoolean); + } else { + reader.skipChildren(); + } + } + if (connectionStringFound && containerNameFound) { + AzureBlobKnowledgeSourceParameters deserializedAzureBlobKnowledgeSourceParameters + = new AzureBlobKnowledgeSourceParameters(connectionString, containerName); + deserializedAzureBlobKnowledgeSourceParameters.identity = identity; + deserializedAzureBlobKnowledgeSourceParameters.folderPath = folderPath; + deserializedAzureBlobKnowledgeSourceParameters.embeddingModel = embeddingModel; + deserializedAzureBlobKnowledgeSourceParameters.chatCompletionModel = chatCompletionModel; + deserializedAzureBlobKnowledgeSourceParameters.ingestionSchedule = ingestionSchedule; + deserializedAzureBlobKnowledgeSourceParameters.createdResources = createdResources; + deserializedAzureBlobKnowledgeSourceParameters.disableImageVerbalization = disableImageVerbalization; + + return deserializedAzureBlobKnowledgeSourceParameters; + } + List missingProperties = new ArrayList<>(); + if (!connectionStringFound) { + missingProperties.add("connectionString"); + } + if (!containerNameFound) { + missingProperties.add("containerName"); + } + + throw new IllegalStateException( + "Missing required property/properties: " + String.join(", ", missingProperties)); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgent.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgent.java index 2237923e3fb2..abe9cd3b0a7c 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgent.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgent.java @@ -34,10 +34,16 @@ public final class KnowledgeAgent implements JsonSerializable { private final List models; /* - * The targetIndexes property. + * The knowledgeSources property. */ @Generated - private final List targetIndexes; + private final List knowledgeSources; + + /* + * The outputConfiguration property. + */ + @Generated + private KnowledgeAgentOutputConfiguration outputConfiguration; /* * Guardrails to limit how much resources are utilized for a single agent retrieval request. @@ -45,6 +51,12 @@ public final class KnowledgeAgent implements JsonSerializable { @Generated private KnowledgeAgentRequestLimits requestLimits; + /* + * Instructions considered by the knowledge agent when developing query plan. + */ + @Generated + private String retrievalInstructions; + /* * The ETag of the agent. */ @@ -74,14 +86,14 @@ public final class KnowledgeAgent implements JsonSerializable { * * @param name the name value to set. * @param models the models value to set. - * @param targetIndexes the targetIndexes value to set. + * @param knowledgeSources the knowledgeSources value to set. */ @Generated public KnowledgeAgent(String name, List models, - List targetIndexes) { + List knowledgeSources) { this.name = name; this.models = models; - this.targetIndexes = targetIndexes; + this.knowledgeSources = knowledgeSources; } /** @@ -105,13 +117,35 @@ public List getModels() { } /** - * Get the targetIndexes property: The targetIndexes property. + * Get the knowledgeSources property: The knowledgeSources property. + * + * @return the knowledgeSources value. + */ + @Generated + public List getKnowledgeSources() { + return this.knowledgeSources; + } + + /** + * Get the outputConfiguration property: The outputConfiguration property. + * + * @return the outputConfiguration value. + */ + @Generated + public KnowledgeAgentOutputConfiguration getOutputConfiguration() { + return this.outputConfiguration; + } + + /** + * Set the outputConfiguration property: The outputConfiguration property. * - * @return the targetIndexes value. + * @param outputConfiguration the outputConfiguration value to set. + * @return the KnowledgeAgent object itself. */ @Generated - public List getTargetIndexes() { - return this.targetIndexes; + public KnowledgeAgent setOutputConfiguration(KnowledgeAgentOutputConfiguration outputConfiguration) { + this.outputConfiguration = outputConfiguration; + return this; } /** @@ -138,6 +172,30 @@ public KnowledgeAgent setRequestLimits(KnowledgeAgentRequestLimits requestLimits return this; } + /** + * Get the retrievalInstructions property: Instructions considered by the knowledge agent when developing query + * plan. + * + * @return the retrievalInstructions value. + */ + @Generated + public String getRetrievalInstructions() { + return this.retrievalInstructions; + } + + /** + * Set the retrievalInstructions property: Instructions considered by the knowledge agent when developing query + * plan. + * + * @param retrievalInstructions the retrievalInstructions value to set. + * @return the KnowledgeAgent object itself. + */ + @Generated + public KnowledgeAgent setRetrievalInstructions(String retrievalInstructions) { + this.retrievalInstructions = retrievalInstructions; + return this; + } + /** * Get the eTag property: The ETag of the agent. * @@ -225,8 +283,11 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeStringField("name", this.name); jsonWriter.writeArrayField("models", this.models, (writer, element) -> writer.writeJson(element)); - jsonWriter.writeArrayField("targetIndexes", this.targetIndexes, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeArrayField("knowledgeSources", this.knowledgeSources, + (writer, element) -> writer.writeJson(element)); + jsonWriter.writeJsonField("outputConfiguration", this.outputConfiguration); jsonWriter.writeJsonField("requestLimits", this.requestLimits); + jsonWriter.writeStringField("retrievalInstructions", this.retrievalInstructions); jsonWriter.writeStringField("@odata.etag", this.eTag); jsonWriter.writeJsonField("encryptionKey", this.encryptionKey); jsonWriter.writeStringField("description", this.description); @@ -249,9 +310,11 @@ public static KnowledgeAgent fromJson(JsonReader jsonReader) throws IOException String name = null; boolean modelsFound = false; List models = null; - boolean targetIndexesFound = false; - List targetIndexes = null; + boolean knowledgeSourcesFound = false; + List knowledgeSources = null; + KnowledgeAgentOutputConfiguration outputConfiguration = null; KnowledgeAgentRequestLimits requestLimits = null; + String retrievalInstructions = null; String eTag = null; SearchResourceEncryptionKey encryptionKey = null; String description = null; @@ -265,11 +328,15 @@ public static KnowledgeAgent fromJson(JsonReader jsonReader) throws IOException } else if ("models".equals(fieldName)) { models = reader.readArray(reader1 -> KnowledgeAgentModel.fromJson(reader1)); modelsFound = true; - } else if ("targetIndexes".equals(fieldName)) { - targetIndexes = reader.readArray(reader1 -> KnowledgeAgentTargetIndex.fromJson(reader1)); - targetIndexesFound = true; + } else if ("knowledgeSources".equals(fieldName)) { + knowledgeSources = reader.readArray(reader1 -> KnowledgeSourceReference.fromJson(reader1)); + knowledgeSourcesFound = true; + } else if ("outputConfiguration".equals(fieldName)) { + outputConfiguration = KnowledgeAgentOutputConfiguration.fromJson(reader); } else if ("requestLimits".equals(fieldName)) { requestLimits = KnowledgeAgentRequestLimits.fromJson(reader); + } else if ("retrievalInstructions".equals(fieldName)) { + retrievalInstructions = reader.getString(); } else if ("@odata.etag".equals(fieldName)) { eTag = reader.getString(); } else if ("encryptionKey".equals(fieldName)) { @@ -280,9 +347,11 @@ public static KnowledgeAgent fromJson(JsonReader jsonReader) throws IOException reader.skipChildren(); } } - if (nameFound && modelsFound && targetIndexesFound) { - KnowledgeAgent deserializedKnowledgeAgent = new KnowledgeAgent(name, models, targetIndexes); + if (nameFound && modelsFound && knowledgeSourcesFound) { + KnowledgeAgent deserializedKnowledgeAgent = new KnowledgeAgent(name, models, knowledgeSources); + deserializedKnowledgeAgent.outputConfiguration = outputConfiguration; deserializedKnowledgeAgent.requestLimits = requestLimits; + deserializedKnowledgeAgent.retrievalInstructions = retrievalInstructions; deserializedKnowledgeAgent.eTag = eTag; deserializedKnowledgeAgent.encryptionKey = encryptionKey; deserializedKnowledgeAgent.description = description; @@ -296,8 +365,8 @@ public static KnowledgeAgent fromJson(JsonReader jsonReader) throws IOException if (!modelsFound) { missingProperties.add("models"); } - if (!targetIndexesFound) { - missingProperties.add("targetIndexes"); + if (!knowledgeSourcesFound) { + missingProperties.add("knowledgeSources"); } throw new IllegalStateException( diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfiguration.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfiguration.java new file mode 100644 index 000000000000..1d87a8fb86f3 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfiguration.java @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * The KnowledgeAgentOutputConfiguration model. + */ +@Fluent +public final class KnowledgeAgentOutputConfiguration implements JsonSerializable { + /* + * The output configuration for the agent + */ + @Generated + private KnowledgeAgentOutputConfigurationModality modality; + + /* + * Instructions considered by the knowledge agent when generating answers + */ + @Generated + private String answerInstructions; + + /* + * Indicates whether the agent should attempt to issue the most recent chat message as a direct query to the + * knowledge sources, bypassing the model calls. + */ + @Generated + private Boolean attemptFastPath; + + /* + * Indicates retrieval results should include activity information. + */ + @Generated + private Boolean includeActivity; + + /** + * Creates an instance of KnowledgeAgentOutputConfiguration class. + */ + @Generated + public KnowledgeAgentOutputConfiguration() { + } + + /** + * Get the modality property: The output configuration for the agent. + * + * @return the modality value. + */ + @Generated + public KnowledgeAgentOutputConfigurationModality getModality() { + return this.modality; + } + + /** + * Set the modality property: The output configuration for the agent. + * + * @param modality the modality value to set. + * @return the KnowledgeAgentOutputConfiguration object itself. + */ + @Generated + public KnowledgeAgentOutputConfiguration setModality(KnowledgeAgentOutputConfigurationModality modality) { + this.modality = modality; + return this; + } + + /** + * Get the answerInstructions property: Instructions considered by the knowledge agent when generating answers. + * + * @return the answerInstructions value. + */ + @Generated + public String getAnswerInstructions() { + return this.answerInstructions; + } + + /** + * Set the answerInstructions property: Instructions considered by the knowledge agent when generating answers. + * + * @param answerInstructions the answerInstructions value to set. + * @return the KnowledgeAgentOutputConfiguration object itself. + */ + @Generated + public KnowledgeAgentOutputConfiguration setAnswerInstructions(String answerInstructions) { + this.answerInstructions = answerInstructions; + return this; + } + + /** + * Get the attemptFastPath property: Indicates whether the agent should attempt to issue the most recent chat + * message as a direct query to the knowledge sources, bypassing the model calls. + * + * @return the attemptFastPath value. + */ + @Generated + public Boolean isAttemptFastPath() { + return this.attemptFastPath; + } + + /** + * Set the attemptFastPath property: Indicates whether the agent should attempt to issue the most recent chat + * message as a direct query to the knowledge sources, bypassing the model calls. + * + * @param attemptFastPath the attemptFastPath value to set. + * @return the KnowledgeAgentOutputConfiguration object itself. + */ + @Generated + public KnowledgeAgentOutputConfiguration setAttemptFastPath(Boolean attemptFastPath) { + this.attemptFastPath = attemptFastPath; + return this; + } + + /** + * Get the includeActivity property: Indicates retrieval results should include activity information. + * + * @return the includeActivity value. + */ + @Generated + public Boolean isIncludeActivity() { + return this.includeActivity; + } + + /** + * Set the includeActivity property: Indicates retrieval results should include activity information. + * + * @param includeActivity the includeActivity value to set. + * @return the KnowledgeAgentOutputConfiguration object itself. + */ + @Generated + public KnowledgeAgentOutputConfiguration setIncludeActivity(Boolean includeActivity) { + this.includeActivity = includeActivity; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("modality", this.modality == null ? null : this.modality.toString()); + jsonWriter.writeStringField("answerInstructions", this.answerInstructions); + jsonWriter.writeBooleanField("attemptFastPath", this.attemptFastPath); + jsonWriter.writeBooleanField("includeActivity", this.includeActivity); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentOutputConfiguration from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentOutputConfiguration if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the KnowledgeAgentOutputConfiguration. + */ + @Generated + public static KnowledgeAgentOutputConfiguration fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + KnowledgeAgentOutputConfiguration deserializedKnowledgeAgentOutputConfiguration + = new KnowledgeAgentOutputConfiguration(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("modality".equals(fieldName)) { + deserializedKnowledgeAgentOutputConfiguration.modality + = KnowledgeAgentOutputConfigurationModality.fromString(reader.getString()); + } else if ("answerInstructions".equals(fieldName)) { + deserializedKnowledgeAgentOutputConfiguration.answerInstructions = reader.getString(); + } else if ("attemptFastPath".equals(fieldName)) { + deserializedKnowledgeAgentOutputConfiguration.attemptFastPath + = reader.getNullable(JsonReader::getBoolean); + } else if ("includeActivity".equals(fieldName)) { + deserializedKnowledgeAgentOutputConfiguration.includeActivity + = reader.getNullable(JsonReader::getBoolean); + } else { + reader.skipChildren(); + } + } + + return deserializedKnowledgeAgentOutputConfiguration; + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfigurationModality.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfigurationModality.java new file mode 100644 index 000000000000..326a2092bc87 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputConfigurationModality.java @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The output configuration for the agent. + */ +public final class KnowledgeAgentOutputConfigurationModality + extends ExpandableStringEnum { + /** + * Synthesize an answer for the response payload. + */ + @Generated + public static final KnowledgeAgentOutputConfigurationModality ANSWER_SYNTHESIS = fromString("answerSynthesis"); + + /** + * Return data from the knowledge sources directly without generative alteration. + */ + @Generated + public static final KnowledgeAgentOutputConfigurationModality EXTRACTIVE_DATA = fromString("extractiveData"); + + /** + * Creates a new instance of KnowledgeAgentOutputConfigurationModality value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public KnowledgeAgentOutputConfigurationModality() { + } + + /** + * Creates or finds a KnowledgeAgentOutputConfigurationModality from its string representation. + * + * @param name a name to look for. + * @return the corresponding KnowledgeAgentOutputConfigurationModality. + */ + @Generated + public static KnowledgeAgentOutputConfigurationModality fromString(String name) { + return fromString(name, KnowledgeAgentOutputConfigurationModality.class); + } + + /** + * Gets known KnowledgeAgentOutputConfigurationModality values. + * + * @return known KnowledgeAgentOutputConfigurationModality values. + */ + @Generated + public static Collection values() { + return values(KnowledgeAgentOutputConfigurationModality.class); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java new file mode 100644 index 000000000000..63e968afa46a --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * Procedural optimizations the agent should perform during retrieval. + */ +public final class KnowledgeAgentOutputOptimization extends ExpandableStringEnum { + /** + * Attempt to avoid a model call by issuing the most recent chat message as a direct query. + */ + @Generated + public static final KnowledgeAgentOutputOptimization ATTEMPT_BYPASS_MODEL = fromString("attemptBypassModel"); + + /** + * Creates a new instance of KnowledgeAgentOutputOptimization value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public KnowledgeAgentOutputOptimization() { + } + + /** + * Creates or finds a KnowledgeAgentOutputOptimization from its string representation. + * + * @param name a name to look for. + * @return the corresponding KnowledgeAgentOutputOptimization. + */ + @Generated + public static KnowledgeAgentOutputOptimization fromString(String name) { + return fromString(name, KnowledgeAgentOutputOptimization.class); + } + + /** + * Gets known KnowledgeAgentOutputOptimization values. + * + * @return known KnowledgeAgentOutputOptimization values. + */ + @Generated + public static Collection values() { + return values(KnowledgeAgentOutputOptimization.class); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentTargetIndex.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentTargetIndex.java deleted file mode 100644 index 9da2f2edb722..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentTargetIndex.java +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.indexes.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * The KnowledgeAgentTargetIndex model. - */ -@Fluent -public final class KnowledgeAgentTargetIndex implements JsonSerializable { - /* - * The name of the target index. - */ - @Generated - private final String indexName; - - /* - * A threshold for reranking results (range: 0-4). - */ - @Generated - private Float defaultRerankerThreshold; - - /* - * Indicates whether reference source data should be included. - */ - @Generated - private Boolean defaultIncludeReferenceSourceData; - - /* - * Limits the number of documents considered for ranking. - */ - @Generated - private Integer defaultMaxDocsForReranker; - - /** - * Creates an instance of KnowledgeAgentTargetIndex class. - * - * @param indexName the indexName value to set. - */ - @Generated - public KnowledgeAgentTargetIndex(String indexName) { - this.indexName = indexName; - } - - /** - * Get the indexName property: The name of the target index. - * - * @return the indexName value. - */ - @Generated - public String getIndexName() { - return this.indexName; - } - - /** - * Get the defaultRerankerThreshold property: A threshold for reranking results (range: 0-4). - * - * @return the defaultRerankerThreshold value. - */ - @Generated - public Float getDefaultRerankerThreshold() { - return this.defaultRerankerThreshold; - } - - /** - * Set the defaultRerankerThreshold property: A threshold for reranking results (range: 0-4). - * - * @param defaultRerankerThreshold the defaultRerankerThreshold value to set. - * @return the KnowledgeAgentTargetIndex object itself. - */ - @Generated - public KnowledgeAgentTargetIndex setDefaultRerankerThreshold(Float defaultRerankerThreshold) { - this.defaultRerankerThreshold = defaultRerankerThreshold; - return this; - } - - /** - * Get the defaultIncludeReferenceSourceData property: Indicates whether reference source data should be included. - * - * @return the defaultIncludeReferenceSourceData value. - */ - @Generated - public Boolean isDefaultIncludeReferenceSourceData() { - return this.defaultIncludeReferenceSourceData; - } - - /** - * Set the defaultIncludeReferenceSourceData property: Indicates whether reference source data should be included. - * - * @param defaultIncludeReferenceSourceData the defaultIncludeReferenceSourceData value to set. - * @return the KnowledgeAgentTargetIndex object itself. - */ - @Generated - public KnowledgeAgentTargetIndex setDefaultIncludeReferenceSourceData(Boolean defaultIncludeReferenceSourceData) { - this.defaultIncludeReferenceSourceData = defaultIncludeReferenceSourceData; - return this; - } - - /** - * Get the defaultMaxDocsForReranker property: Limits the number of documents considered for ranking. - * - * @return the defaultMaxDocsForReranker value. - */ - @Generated - public Integer getDefaultMaxDocsForReranker() { - return this.defaultMaxDocsForReranker; - } - - /** - * Set the defaultMaxDocsForReranker property: Limits the number of documents considered for ranking. - * - * @param defaultMaxDocsForReranker the defaultMaxDocsForReranker value to set. - * @return the KnowledgeAgentTargetIndex object itself. - */ - @Generated - public KnowledgeAgentTargetIndex setDefaultMaxDocsForReranker(Integer defaultMaxDocsForReranker) { - this.defaultMaxDocsForReranker = defaultMaxDocsForReranker; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("indexName", this.indexName); - jsonWriter.writeNumberField("defaultRerankerThreshold", this.defaultRerankerThreshold); - jsonWriter.writeBooleanField("defaultIncludeReferenceSourceData", this.defaultIncludeReferenceSourceData); - jsonWriter.writeNumberField("defaultMaxDocsForReranker", this.defaultMaxDocsForReranker); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of KnowledgeAgentTargetIndex from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of KnowledgeAgentTargetIndex if the JsonReader was pointing to an instance of it, or null if - * it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the KnowledgeAgentTargetIndex. - */ - @Generated - public static KnowledgeAgentTargetIndex fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - boolean indexNameFound = false; - String indexName = null; - Float defaultRerankerThreshold = null; - Boolean defaultIncludeReferenceSourceData = null; - Integer defaultMaxDocsForReranker = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("indexName".equals(fieldName)) { - indexName = reader.getString(); - indexNameFound = true; - } else if ("defaultRerankerThreshold".equals(fieldName)) { - defaultRerankerThreshold = reader.getNullable(JsonReader::getFloat); - } else if ("defaultIncludeReferenceSourceData".equals(fieldName)) { - defaultIncludeReferenceSourceData = reader.getNullable(JsonReader::getBoolean); - } else if ("defaultMaxDocsForReranker".equals(fieldName)) { - defaultMaxDocsForReranker = reader.getNullable(JsonReader::getInt); - } else { - reader.skipChildren(); - } - } - if (indexNameFound) { - KnowledgeAgentTargetIndex deserializedKnowledgeAgentTargetIndex - = new KnowledgeAgentTargetIndex(indexName); - deserializedKnowledgeAgentTargetIndex.defaultRerankerThreshold = defaultRerankerThreshold; - deserializedKnowledgeAgentTargetIndex.defaultIncludeReferenceSourceData - = defaultIncludeReferenceSourceData; - deserializedKnowledgeAgentTargetIndex.defaultMaxDocsForReranker = defaultMaxDocsForReranker; - - return deserializedKnowledgeAgentTargetIndex; - } - throw new IllegalStateException("Missing required property: indexName"); - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java new file mode 100644 index 000000000000..b2dfbfa20f9b --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java @@ -0,0 +1,260 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Represents a knowledge source definition. + */ +@Fluent +public class KnowledgeSource implements JsonSerializable { + /* + * The type of the knowledge source. + */ + @Generated + private KnowledgeSourceKind kind = KnowledgeSourceKind.fromString("KnowledgeSource"); + + /* + * The name of the knowledge source. + */ + @Generated + private final String name; + + /* + * Optional user-defined description. + */ + @Generated + private String description; + + /* + * The ETag of the agent. + */ + @Generated + private String eTag; + + /* + * A description of an encryption key that you create in Azure Key Vault. This key is used to provide an additional + * level of encryption-at-rest for your agent definition when you want full assurance that no one, not even + * Microsoft, can decrypt them. Once you have encrypted your agent definition, it will always remain encrypted. The + * search service will ignore attempts to set this property to null. You can change this property as needed if you + * want to rotate your encryption key; Your agent definition will be unaffected. Encryption with customer-managed + * keys is not available for free search services, and is only available for paid services created on or after + * January 1, 2019. + */ + @Generated + private SearchResourceEncryptionKey encryptionKey; + + /** + * Creates an instance of KnowledgeSource class. + * + * @param name the name value to set. + */ + @Generated + public KnowledgeSource(String name) { + this.name = name; + } + + /** + * Get the kind property: The type of the knowledge source. + * + * @return the kind value. + */ + @Generated + public KnowledgeSourceKind getKind() { + return this.kind; + } + + /** + * Get the name property: The name of the knowledge source. + * + * @return the name value. + */ + @Generated + public String getName() { + return this.name; + } + + /** + * Get the description property: Optional user-defined description. + * + * @return the description value. + */ + @Generated + public String getDescription() { + return this.description; + } + + /** + * Set the description property: Optional user-defined description. + * + * @param description the description value to set. + * @return the KnowledgeSource object itself. + */ + @Generated + public KnowledgeSource setDescription(String description) { + this.description = description; + return this; + } + + /** + * Get the eTag property: The ETag of the agent. + * + * @return the eTag value. + */ + @Generated + public String getETag() { + return this.eTag; + } + + /** + * Set the eTag property: The ETag of the agent. + * + * @param eTag the eTag value to set. + * @return the KnowledgeSource object itself. + */ + @Generated + public KnowledgeSource setETag(String eTag) { + this.eTag = eTag; + return this; + } + + /** + * Get the encryptionKey property: A description of an encryption key that you create in Azure Key Vault. This key + * is used to provide an additional level of encryption-at-rest for your agent definition when you want full + * assurance that no one, not even Microsoft, can decrypt them. Once you have encrypted your agent definition, it + * will always remain encrypted. The search service will ignore attempts to set this property to null. You can + * change this property as needed if you want to rotate your encryption key; Your agent definition will be + * unaffected. Encryption with customer-managed keys is not available for free search services, and is only + * available for paid services created on or after January 1, 2019. + * + * @return the encryptionKey value. + */ + @Generated + public SearchResourceEncryptionKey getEncryptionKey() { + return this.encryptionKey; + } + + /** + * Set the encryptionKey property: A description of an encryption key that you create in Azure Key Vault. This key + * is used to provide an additional level of encryption-at-rest for your agent definition when you want full + * assurance that no one, not even Microsoft, can decrypt them. Once you have encrypted your agent definition, it + * will always remain encrypted. The search service will ignore attempts to set this property to null. You can + * change this property as needed if you want to rotate your encryption key; Your agent definition will be + * unaffected. Encryption with customer-managed keys is not available for free search services, and is only + * available for paid services created on or after January 1, 2019. + * + * @param encryptionKey the encryptionKey value to set. + * @return the KnowledgeSource object itself. + */ + @Generated + public KnowledgeSource setEncryptionKey(SearchResourceEncryptionKey encryptionKey) { + this.encryptionKey = encryptionKey; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("name", this.name); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeStringField("description", this.description); + jsonWriter.writeStringField("@odata.etag", this.eTag); + jsonWriter.writeJsonField("encryptionKey", this.encryptionKey); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeSource from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeSource if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeSource. + */ + @Generated + public static KnowledgeSource fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + readerToUse.nextToken(); // Prepare for reading + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("kind".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("searchIndex".equals(discriminatorValue)) { + return SearchIndexKnowledgeSource.fromJson(readerToUse.reset()); + } else if ("web".equals(discriminatorValue)) { + return WebKnowledgeSource.fromJson(readerToUse.reset()); + } else if ("azureBlob".equals(discriminatorValue)) { + return AzureBlobKnowledgeSource.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static KnowledgeSource fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean nameFound = false; + String name = null; + KnowledgeSourceKind kind = null; + String description = null; + String eTag = null; + SearchResourceEncryptionKey encryptionKey = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("name".equals(fieldName)) { + name = reader.getString(); + nameFound = true; + } else if ("kind".equals(fieldName)) { + kind = KnowledgeSourceKind.fromString(reader.getString()); + } else if ("description".equals(fieldName)) { + description = reader.getString(); + } else if ("@odata.etag".equals(fieldName)) { + eTag = reader.getString(); + } else if ("encryptionKey".equals(fieldName)) { + encryptionKey = SearchResourceEncryptionKey.fromJson(reader); + } else { + reader.skipChildren(); + } + } + if (nameFound) { + KnowledgeSource deserializedKnowledgeSource = new KnowledgeSource(name); + deserializedKnowledgeSource.kind = kind; + deserializedKnowledgeSource.description = description; + deserializedKnowledgeSource.eTag = eTag; + deserializedKnowledgeSource.encryptionKey = encryptionKey; + + return deserializedKnowledgeSource; + } + throw new IllegalStateException("Missing required property: name"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java new file mode 100644 index 000000000000..2b749993a7fa --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The kind of the knowledge source. + */ +public final class KnowledgeSourceKind extends ExpandableStringEnum { + /** + * A knowledge source that reads data from a Search Index. + */ + @Generated + public static final KnowledgeSourceKind SEARCH_INDEX = fromString("searchIndex"); + + /** + * A knowledge source that read and ingest data from Azure Blob Storage to a Search Index. + */ + @Generated + public static final KnowledgeSourceKind AZURE_BLOB = fromString("azureBlob"); + + /** + * A knowledge source that reads data from the web. + */ + @Generated + public static final KnowledgeSourceKind WEB = fromString("web"); + + /** + * Creates a new instance of KnowledgeSourceKind value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public KnowledgeSourceKind() { + } + + /** + * Creates or finds a KnowledgeSourceKind from its string representation. + * + * @param name a name to look for. + * @return the corresponding KnowledgeSourceKind. + */ + @Generated + public static KnowledgeSourceKind fromString(String name) { + return fromString(name, KnowledgeSourceKind.class); + } + + /** + * Gets known KnowledgeSourceKind values. + * + * @return known KnowledgeSourceKind values. + */ + @Generated + public static Collection values() { + return values(KnowledgeSourceKind.class); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceReference.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceReference.java new file mode 100644 index 000000000000..f8acf874dff9 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceReference.java @@ -0,0 +1,267 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * The KnowledgeSourceReference model. + */ +@Fluent +public final class KnowledgeSourceReference implements JsonSerializable { + /* + * The name of the knowledge source. + */ + @Generated + private final String name; + + /* + * Indicates whether references should be included for data retrieved from this source. + */ + @Generated + private Boolean includeReferences; + + /* + * Indicates whether references should include the structured data obtained during retrieval in their payload. + */ + @Generated + private Boolean includeReferenceSourceData; + + /* + * Indicates that this knowledge source should bypass source selection and always be queried at retrieval time. + */ + @Generated + private Boolean alwaysQuerySource; + + /* + * The maximum number of queries that can be issued at a time when retrieving data from this source. + */ + @Generated + private Integer maxSubQueries; + + /* + * The reranker threshold all retrieved documents must meet to be included in the response. + */ + @Generated + private Float rerankerThreshold; + + /** + * Creates an instance of KnowledgeSourceReference class. + * + * @param name the name value to set. + */ + @Generated + public KnowledgeSourceReference(String name) { + this.name = name; + } + + /** + * Get the name property: The name of the knowledge source. + * + * @return the name value. + */ + @Generated + public String getName() { + return this.name; + } + + /** + * Get the includeReferences property: Indicates whether references should be included for data retrieved from this + * source. + * + * @return the includeReferences value. + */ + @Generated + public Boolean isIncludeReferences() { + return this.includeReferences; + } + + /** + * Set the includeReferences property: Indicates whether references should be included for data retrieved from this + * source. + * + * @param includeReferences the includeReferences value to set. + * @return the KnowledgeSourceReference object itself. + */ + @Generated + public KnowledgeSourceReference setIncludeReferences(Boolean includeReferences) { + this.includeReferences = includeReferences; + return this; + } + + /** + * Get the includeReferenceSourceData property: Indicates whether references should include the structured data + * obtained during retrieval in their payload. + * + * @return the includeReferenceSourceData value. + */ + @Generated + public Boolean isIncludeReferenceSourceData() { + return this.includeReferenceSourceData; + } + + /** + * Set the includeReferenceSourceData property: Indicates whether references should include the structured data + * obtained during retrieval in their payload. + * + * @param includeReferenceSourceData the includeReferenceSourceData value to set. + * @return the KnowledgeSourceReference object itself. + */ + @Generated + public KnowledgeSourceReference setIncludeReferenceSourceData(Boolean includeReferenceSourceData) { + this.includeReferenceSourceData = includeReferenceSourceData; + return this; + } + + /** + * Get the alwaysQuerySource property: Indicates that this knowledge source should bypass source selection and + * always be queried at retrieval time. + * + * @return the alwaysQuerySource value. + */ + @Generated + public Boolean isAlwaysQuerySource() { + return this.alwaysQuerySource; + } + + /** + * Set the alwaysQuerySource property: Indicates that this knowledge source should bypass source selection and + * always be queried at retrieval time. + * + * @param alwaysQuerySource the alwaysQuerySource value to set. + * @return the KnowledgeSourceReference object itself. + */ + @Generated + public KnowledgeSourceReference setAlwaysQuerySource(Boolean alwaysQuerySource) { + this.alwaysQuerySource = alwaysQuerySource; + return this; + } + + /** + * Get the maxSubQueries property: The maximum number of queries that can be issued at a time when retrieving data + * from this source. + * + * @return the maxSubQueries value. + */ + @Generated + public Integer getMaxSubQueries() { + return this.maxSubQueries; + } + + /** + * Set the maxSubQueries property: The maximum number of queries that can be issued at a time when retrieving data + * from this source. + * + * @param maxSubQueries the maxSubQueries value to set. + * @return the KnowledgeSourceReference object itself. + */ + @Generated + public KnowledgeSourceReference setMaxSubQueries(Integer maxSubQueries) { + this.maxSubQueries = maxSubQueries; + return this; + } + + /** + * Get the rerankerThreshold property: The reranker threshold all retrieved documents must meet to be included in + * the response. + * + * @return the rerankerThreshold value. + */ + @Generated + public Float getRerankerThreshold() { + return this.rerankerThreshold; + } + + /** + * Set the rerankerThreshold property: The reranker threshold all retrieved documents must meet to be included in + * the response. + * + * @param rerankerThreshold the rerankerThreshold value to set. + * @return the KnowledgeSourceReference object itself. + */ + @Generated + public KnowledgeSourceReference setRerankerThreshold(Float rerankerThreshold) { + this.rerankerThreshold = rerankerThreshold; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("name", this.name); + jsonWriter.writeBooleanField("includeReferences", this.includeReferences); + jsonWriter.writeBooleanField("includeReferenceSourceData", this.includeReferenceSourceData); + jsonWriter.writeBooleanField("alwaysQuerySource", this.alwaysQuerySource); + jsonWriter.writeNumberField("maxSubQueries", this.maxSubQueries); + jsonWriter.writeNumberField("rerankerThreshold", this.rerankerThreshold); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeSourceReference from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeSourceReference if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeSourceReference. + */ + @Generated + public static KnowledgeSourceReference fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean nameFound = false; + String name = null; + Boolean includeReferences = null; + Boolean includeReferenceSourceData = null; + Boolean alwaysQuerySource = null; + Integer maxSubQueries = null; + Float rerankerThreshold = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("name".equals(fieldName)) { + name = reader.getString(); + nameFound = true; + } else if ("includeReferences".equals(fieldName)) { + includeReferences = reader.getNullable(JsonReader::getBoolean); + } else if ("includeReferenceSourceData".equals(fieldName)) { + includeReferenceSourceData = reader.getNullable(JsonReader::getBoolean); + } else if ("alwaysQuerySource".equals(fieldName)) { + alwaysQuerySource = reader.getNullable(JsonReader::getBoolean); + } else if ("maxSubQueries".equals(fieldName)) { + maxSubQueries = reader.getNullable(JsonReader::getInt); + } else if ("rerankerThreshold".equals(fieldName)) { + rerankerThreshold = reader.getNullable(JsonReader::getFloat); + } else { + reader.skipChildren(); + } + } + if (nameFound) { + KnowledgeSourceReference deserializedKnowledgeSourceReference = new KnowledgeSourceReference(name); + deserializedKnowledgeSourceReference.includeReferences = includeReferences; + deserializedKnowledgeSourceReference.includeReferenceSourceData = includeReferenceSourceData; + deserializedKnowledgeSourceReference.alwaysQuerySource = alwaysQuerySource; + deserializedKnowledgeSourceReference.maxSubQueries = maxSubQueries; + deserializedKnowledgeSourceReference.rerankerThreshold = rerankerThreshold; + + return deserializedKnowledgeSourceReference; + } + throw new IllegalStateException("Missing required property: name"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeSourcesResult.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeSourcesResult.java new file mode 100644 index 000000000000..6c313dda8a48 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeSourcesResult.java @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * The ListKnowledgeSourcesResult model. + */ +@Immutable +public final class ListKnowledgeSourcesResult implements JsonSerializable { + /* + * The value property. + */ + @Generated + private final List knowledgeSources; + + /** + * Creates an instance of ListKnowledgeSourcesResult class. + * + * @param knowledgeSources the knowledgeSources value to set. + */ + @Generated + public ListKnowledgeSourcesResult(List knowledgeSources) { + this.knowledgeSources = knowledgeSources; + } + + /** + * Get the knowledgeSources property: The value property. + * + * @return the knowledgeSources value. + */ + @Generated + public List getKnowledgeSources() { + return this.knowledgeSources; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeArrayField("value", this.knowledgeSources, (writer, element) -> writer.writeJson(element)); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of ListKnowledgeSourcesResult from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of ListKnowledgeSourcesResult if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the ListKnowledgeSourcesResult. + */ + @Generated + public static ListKnowledgeSourcesResult fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean knowledgeSourcesFound = false; + List knowledgeSources = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("value".equals(fieldName)) { + knowledgeSources = reader.readArray(reader1 -> KnowledgeSource.fromJson(reader1)); + knowledgeSourcesFound = true; + } else { + reader.skipChildren(); + } + } + if (knowledgeSourcesFound) { + return new ListKnowledgeSourcesResult(knowledgeSources); + } + throw new IllegalStateException("Missing required property: value"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSource.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSource.java new file mode 100644 index 000000000000..27c7f01462d5 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSource.java @@ -0,0 +1,178 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Knowledge Source targeting a search index. + */ +@Fluent +public final class SearchIndexKnowledgeSource extends KnowledgeSource { + /* + * The type of the knowledge source. + */ + @Generated + private KnowledgeSourceKind kind = KnowledgeSourceKind.SEARCH_INDEX; + + /* + * The parameters for the knowledge source. + */ + @Generated + private final SearchIndexKnowledgeSourceParameters searchIndexParameters; + + /** + * Creates an instance of SearchIndexKnowledgeSource class. + * + * @param name the name value to set. + * @param searchIndexParameters the searchIndexParameters value to set. + */ + @Generated + public SearchIndexKnowledgeSource(String name, SearchIndexKnowledgeSourceParameters searchIndexParameters) { + super(name); + this.searchIndexParameters = searchIndexParameters; + } + + /** + * Get the kind property: The type of the knowledge source. + * + * @return the kind value. + */ + @Generated + @Override + public KnowledgeSourceKind getKind() { + return this.kind; + } + + /** + * Get the searchIndexParameters property: The parameters for the knowledge source. + * + * @return the searchIndexParameters value. + */ + @Generated + public SearchIndexKnowledgeSourceParameters getSearchIndexParameters() { + return this.searchIndexParameters; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public SearchIndexKnowledgeSource setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public SearchIndexKnowledgeSource setETag(String eTag) { + super.setETag(eTag); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public SearchIndexKnowledgeSource setEncryptionKey(SearchResourceEncryptionKey encryptionKey) { + super.setEncryptionKey(encryptionKey); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("name", getName()); + jsonWriter.writeStringField("description", getDescription()); + jsonWriter.writeStringField("@odata.etag", getETag()); + jsonWriter.writeJsonField("encryptionKey", getEncryptionKey()); + jsonWriter.writeJsonField("searchIndexParameters", this.searchIndexParameters); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of SearchIndexKnowledgeSource from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of SearchIndexKnowledgeSource if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the SearchIndexKnowledgeSource. + */ + @Generated + public static SearchIndexKnowledgeSource fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean nameFound = false; + String name = null; + String description = null; + String eTag = null; + SearchResourceEncryptionKey encryptionKey = null; + boolean searchIndexParametersFound = false; + SearchIndexKnowledgeSourceParameters searchIndexParameters = null; + KnowledgeSourceKind kind = KnowledgeSourceKind.SEARCH_INDEX; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("name".equals(fieldName)) { + name = reader.getString(); + nameFound = true; + } else if ("description".equals(fieldName)) { + description = reader.getString(); + } else if ("@odata.etag".equals(fieldName)) { + eTag = reader.getString(); + } else if ("encryptionKey".equals(fieldName)) { + encryptionKey = SearchResourceEncryptionKey.fromJson(reader); + } else if ("searchIndexParameters".equals(fieldName)) { + searchIndexParameters = SearchIndexKnowledgeSourceParameters.fromJson(reader); + searchIndexParametersFound = true; + } else if ("kind".equals(fieldName)) { + kind = KnowledgeSourceKind.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + if (nameFound && searchIndexParametersFound) { + SearchIndexKnowledgeSource deserializedSearchIndexKnowledgeSource + = new SearchIndexKnowledgeSource(name, searchIndexParameters); + deserializedSearchIndexKnowledgeSource.setDescription(description); + deserializedSearchIndexKnowledgeSource.setETag(eTag); + deserializedSearchIndexKnowledgeSource.setEncryptionKey(encryptionKey); + deserializedSearchIndexKnowledgeSource.kind = kind; + + return deserializedSearchIndexKnowledgeSource; + } + List missingProperties = new ArrayList<>(); + if (!nameFound) { + missingProperties.add("name"); + } + if (!searchIndexParametersFound) { + missingProperties.add("searchIndexParameters"); + } + + throw new IllegalStateException( + "Missing required property/properties: " + String.join(", ", missingProperties)); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSourceParameters.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSourceParameters.java new file mode 100644 index 000000000000..9310d7eaf239 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexKnowledgeSourceParameters.java @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Parameters for search index knowledge source. + */ +@Fluent +public final class SearchIndexKnowledgeSourceParameters + implements JsonSerializable { + /* + * The name of the Search index. + */ + @Generated + private final String searchIndexName; + + /* + * Used to request additional fields for referenced source data. + */ + @Generated + private String sourceDataSelect; + + /** + * Creates an instance of SearchIndexKnowledgeSourceParameters class. + * + * @param searchIndexName the searchIndexName value to set. + */ + @Generated + public SearchIndexKnowledgeSourceParameters(String searchIndexName) { + this.searchIndexName = searchIndexName; + } + + /** + * Get the searchIndexName property: The name of the Search index. + * + * @return the searchIndexName value. + */ + @Generated + public String getSearchIndexName() { + return this.searchIndexName; + } + + /** + * Get the sourceDataSelect property: Used to request additional fields for referenced source data. + * + * @return the sourceDataSelect value. + */ + @Generated + public String getSourceDataSelect() { + return this.sourceDataSelect; + } + + /** + * Set the sourceDataSelect property: Used to request additional fields for referenced source data. + * + * @param sourceDataSelect the sourceDataSelect value to set. + * @return the SearchIndexKnowledgeSourceParameters object itself. + */ + @Generated + public SearchIndexKnowledgeSourceParameters setSourceDataSelect(String sourceDataSelect) { + this.sourceDataSelect = sourceDataSelect; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("searchIndexName", this.searchIndexName); + jsonWriter.writeStringField("sourceDataSelect", this.sourceDataSelect); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of SearchIndexKnowledgeSourceParameters from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of SearchIndexKnowledgeSourceParameters if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the SearchIndexKnowledgeSourceParameters. + */ + @Generated + public static SearchIndexKnowledgeSourceParameters fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean searchIndexNameFound = false; + String searchIndexName = null; + String sourceDataSelect = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("searchIndexName".equals(fieldName)) { + searchIndexName = reader.getString(); + searchIndexNameFound = true; + } else if ("sourceDataSelect".equals(fieldName)) { + sourceDataSelect = reader.getString(); + } else { + reader.skipChildren(); + } + } + if (searchIndexNameFound) { + SearchIndexKnowledgeSourceParameters deserializedSearchIndexKnowledgeSourceParameters + = new SearchIndexKnowledgeSourceParameters(searchIndexName); + deserializedSearchIndexKnowledgeSourceParameters.sourceDataSelect = sourceDataSelect; + + return deserializedSearchIndexKnowledgeSourceParameters; + } + throw new IllegalStateException("Missing required property: searchIndexName"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerDataSourceConnection.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerDataSourceConnection.java index 7e2b3baf61d9..c502a9fe7343 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerDataSourceConnection.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerDataSourceConnection.java @@ -39,6 +39,13 @@ public final class SearchIndexerDataSourceConnection implements JsonSerializable @Generated private SearchIndexerDataSourceType type; + /* + * A specific type of the data source, in case the resource is capable of different modalities. For example, + * 'MongoDb' for certain 'cosmosDb' accounts. + */ + @Generated + private String subType; + /* * Credentials for the datasource. */ @@ -159,6 +166,17 @@ public SearchIndexerDataSourceConnection setType(SearchIndexerDataSourceType typ return this; } + /** + * Get the subType property: A specific type of the data source, in case the resource is capable of different + * modalities. For example, 'MongoDb' for certain 'cosmosDb' accounts. + * + * @return the subType value. + */ + @Generated + public String getSubType() { + return this.subType; + } + /** * Get the container property: The data container for the datasource. * @@ -370,6 +388,7 @@ public static SearchIndexerDataSourceConnection fromJson(JsonReader jsonReader) String name = null; String description = null; SearchIndexerDataSourceType type = null; + String subType = null; DataSourceCredentials credentials = null; SearchIndexerDataContainer container = null; SearchIndexerDataIdentity identity = null; @@ -388,6 +407,8 @@ public static SearchIndexerDataSourceConnection fromJson(JsonReader jsonReader) description = reader.getString(); } else if ("type".equals(fieldName)) { type = SearchIndexerDataSourceType.fromString(reader.getString()); + } else if ("subType".equals(fieldName)) { + subType = reader.getString(); } else if ("credentials".equals(fieldName)) { credentials = DataSourceCredentials.fromJson(reader); } else if ("container".equals(fieldName)) { @@ -414,6 +435,7 @@ public static SearchIndexerDataSourceConnection fromJson(JsonReader jsonReader) = new SearchIndexerDataSourceConnection(name); deserializedSearchIndexerDataSourceConnection.description = description; deserializedSearchIndexerDataSourceConnection.type = type; + deserializedSearchIndexerDataSourceConnection.subType = subType; deserializedSearchIndexerDataSourceConnection.credentials = credentials; deserializedSearchIndexerDataSourceConnection.container = container; deserializedSearchIndexerDataSourceConnection.identity = identity; diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java index 71df9706c0fb..cdf07db54784 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java @@ -21,6 +21,12 @@ */ @Immutable public final class SearchIndexerStatus implements JsonSerializable { + /* + * The name of the indexer. + */ + @Generated + private final String name; + /* * Overall indexer status. */ @@ -54,18 +60,30 @@ public final class SearchIndexerStatus implements JsonSerializable executionHistory, + public SearchIndexerStatus(String name, IndexerStatus status, List executionHistory, SearchIndexerLimits limits) { + this.name = name; this.status = status; this.executionHistory = executionHistory; this.limits = limits; } + /** + * Get the name property: The name of the indexer. + * + * @return the name value. + */ + @Generated + public String getName() { + return this.name; + } + /** * Get the status property: Overall indexer status. * @@ -139,6 +157,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { @Generated public static SearchIndexerStatus fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { + boolean nameFound = false; + String name = null; boolean statusFound = false; IndexerStatus status = null; boolean executionHistoryFound = false; @@ -151,7 +171,10 @@ public static SearchIndexerStatus fromJson(JsonReader jsonReader) throws IOExcep String fieldName = reader.getFieldName(); reader.nextToken(); - if ("status".equals(fieldName)) { + if ("name".equals(fieldName)) { + name = reader.getString(); + nameFound = true; + } else if ("status".equals(fieldName)) { status = IndexerStatus.fromString(reader.getString()); statusFound = true; } else if ("executionHistory".equals(fieldName)) { @@ -168,15 +191,18 @@ public static SearchIndexerStatus fromJson(JsonReader jsonReader) throws IOExcep reader.skipChildren(); } } - if (statusFound && executionHistoryFound && limitsFound) { + if (nameFound && statusFound && executionHistoryFound && limitsFound) { SearchIndexerStatus deserializedSearchIndexerStatus - = new SearchIndexerStatus(status, executionHistory, limits); + = new SearchIndexerStatus(name, status, executionHistory, limits); deserializedSearchIndexerStatus.lastResult = lastResult; deserializedSearchIndexerStatus.currentState = currentState; return deserializedSearchIndexerStatus; } List missingProperties = new ArrayList<>(); + if (!nameFound) { + missingProperties.add("name"); + } if (!statusFound) { missingProperties.add("status"); } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSource.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSource.java new file mode 100644 index 000000000000..ab877bc00f8b --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSource.java @@ -0,0 +1,177 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Knowledge Source targeting web results. + */ +@Fluent +public final class WebKnowledgeSource extends KnowledgeSource { + /* + * The type of the knowledge source. + */ + @Generated + private KnowledgeSourceKind kind = KnowledgeSourceKind.WEB; + + /* + * The parameters for the knowledge source. + */ + @Generated + private final WebKnowledgeSourceParameters webParameters; + + /** + * Creates an instance of WebKnowledgeSource class. + * + * @param name the name value to set. + * @param webParameters the webParameters value to set. + */ + @Generated + public WebKnowledgeSource(String name, WebKnowledgeSourceParameters webParameters) { + super(name); + this.webParameters = webParameters; + } + + /** + * Get the kind property: The type of the knowledge source. + * + * @return the kind value. + */ + @Generated + @Override + public KnowledgeSourceKind getKind() { + return this.kind; + } + + /** + * Get the webParameters property: The parameters for the knowledge source. + * + * @return the webParameters value. + */ + @Generated + public WebKnowledgeSourceParameters getWebParameters() { + return this.webParameters; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public WebKnowledgeSource setDescription(String description) { + super.setDescription(description); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public WebKnowledgeSource setETag(String eTag) { + super.setETag(eTag); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public WebKnowledgeSource setEncryptionKey(SearchResourceEncryptionKey encryptionKey) { + super.setEncryptionKey(encryptionKey); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("name", getName()); + jsonWriter.writeStringField("description", getDescription()); + jsonWriter.writeStringField("@odata.etag", getETag()); + jsonWriter.writeJsonField("encryptionKey", getEncryptionKey()); + jsonWriter.writeJsonField("webParameters", this.webParameters); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of WebKnowledgeSource from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of WebKnowledgeSource if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the WebKnowledgeSource. + */ + @Generated + public static WebKnowledgeSource fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean nameFound = false; + String name = null; + String description = null; + String eTag = null; + SearchResourceEncryptionKey encryptionKey = null; + boolean webParametersFound = false; + WebKnowledgeSourceParameters webParameters = null; + KnowledgeSourceKind kind = KnowledgeSourceKind.WEB; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("name".equals(fieldName)) { + name = reader.getString(); + nameFound = true; + } else if ("description".equals(fieldName)) { + description = reader.getString(); + } else if ("@odata.etag".equals(fieldName)) { + eTag = reader.getString(); + } else if ("encryptionKey".equals(fieldName)) { + encryptionKey = SearchResourceEncryptionKey.fromJson(reader); + } else if ("webParameters".equals(fieldName)) { + webParameters = WebKnowledgeSourceParameters.fromJson(reader); + webParametersFound = true; + } else if ("kind".equals(fieldName)) { + kind = KnowledgeSourceKind.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + if (nameFound && webParametersFound) { + WebKnowledgeSource deserializedWebKnowledgeSource = new WebKnowledgeSource(name, webParameters); + deserializedWebKnowledgeSource.setDescription(description); + deserializedWebKnowledgeSource.setETag(eTag); + deserializedWebKnowledgeSource.setEncryptionKey(encryptionKey); + deserializedWebKnowledgeSource.kind = kind; + + return deserializedWebKnowledgeSource; + } + List missingProperties = new ArrayList<>(); + if (!nameFound) { + missingProperties.add("name"); + } + if (!webParametersFound) { + missingProperties.add("webParameters"); + } + + throw new IllegalStateException( + "Missing required property/properties: " + String.join(", ", missingProperties)); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java new file mode 100644 index 000000000000..e16d84810311 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java @@ -0,0 +1,160 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Configuration for web knowledge source domain. + */ +@Fluent +public final class WebKnowledgeSourceAllowedDomain implements JsonSerializable { + /* + * The address of the domain. + */ + @Generated + private final String address; + + /* + * whether or not to include subpages from this domain. + */ + @Generated + private Boolean includeSubpages; + + /* + * The ranking adjustment to perform on the web results. + */ + @Generated + private WebKnowledgeSourceRankingAdjustment rankingAdjustment; + + /** + * Creates an instance of WebKnowledgeSourceAllowedDomain class. + * + * @param address the address value to set. + */ + @Generated + public WebKnowledgeSourceAllowedDomain(String address) { + this.address = address; + } + + /** + * Get the address property: The address of the domain. + * + * @return the address value. + */ + @Generated + public String getAddress() { + return this.address; + } + + /** + * Get the includeSubpages property: whether or not to include subpages from this domain. + * + * @return the includeSubpages value. + */ + @Generated + public Boolean isIncludeSubpages() { + return this.includeSubpages; + } + + /** + * Set the includeSubpages property: whether or not to include subpages from this domain. + * + * @param includeSubpages the includeSubpages value to set. + * @return the WebKnowledgeSourceAllowedDomain object itself. + */ + @Generated + public WebKnowledgeSourceAllowedDomain setIncludeSubpages(Boolean includeSubpages) { + this.includeSubpages = includeSubpages; + return this; + } + + /** + * Get the rankingAdjustment property: The ranking adjustment to perform on the web results. + * + * @return the rankingAdjustment value. + */ + @Generated + public WebKnowledgeSourceRankingAdjustment getRankingAdjustment() { + return this.rankingAdjustment; + } + + /** + * Set the rankingAdjustment property: The ranking adjustment to perform on the web results. + * + * @param rankingAdjustment the rankingAdjustment value to set. + * @return the WebKnowledgeSourceAllowedDomain object itself. + */ + @Generated + public WebKnowledgeSourceAllowedDomain setRankingAdjustment(WebKnowledgeSourceRankingAdjustment rankingAdjustment) { + this.rankingAdjustment = rankingAdjustment; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("address", this.address); + jsonWriter.writeBooleanField("includeSubpages", this.includeSubpages); + jsonWriter.writeStringField("rankingAdjustment", + this.rankingAdjustment == null ? null : this.rankingAdjustment.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of WebKnowledgeSourceAllowedDomain from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of WebKnowledgeSourceAllowedDomain if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the WebKnowledgeSourceAllowedDomain. + */ + @Generated + public static WebKnowledgeSourceAllowedDomain fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean addressFound = false; + String address = null; + Boolean includeSubpages = null; + WebKnowledgeSourceRankingAdjustment rankingAdjustment = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("address".equals(fieldName)) { + address = reader.getString(); + addressFound = true; + } else if ("includeSubpages".equals(fieldName)) { + includeSubpages = reader.getNullable(JsonReader::getBoolean); + } else if ("rankingAdjustment".equals(fieldName)) { + rankingAdjustment = WebKnowledgeSourceRankingAdjustment.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + if (addressFound) { + WebKnowledgeSourceAllowedDomain deserializedWebKnowledgeSourceAllowedDomain + = new WebKnowledgeSourceAllowedDomain(address); + deserializedWebKnowledgeSourceAllowedDomain.includeSubpages = includeSubpages; + deserializedWebKnowledgeSourceAllowedDomain.rankingAdjustment = rankingAdjustment; + + return deserializedWebKnowledgeSourceAllowedDomain; + } + throw new IllegalStateException("Missing required property: address"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java new file mode 100644 index 000000000000..16676d790a15 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Configuration for web knowledge source domain. + */ +@Fluent +public final class WebKnowledgeSourceBlockedDomain implements JsonSerializable { + /* + * The address of the domain. + */ + @Generated + private final String address; + + /* + * whether or not to include subpages from this domain. + */ + @Generated + private Boolean includeSubpages; + + /** + * Creates an instance of WebKnowledgeSourceBlockedDomain class. + * + * @param address the address value to set. + */ + @Generated + public WebKnowledgeSourceBlockedDomain(String address) { + this.address = address; + } + + /** + * Get the address property: The address of the domain. + * + * @return the address value. + */ + @Generated + public String getAddress() { + return this.address; + } + + /** + * Get the includeSubpages property: whether or not to include subpages from this domain. + * + * @return the includeSubpages value. + */ + @Generated + public Boolean isIncludeSubpages() { + return this.includeSubpages; + } + + /** + * Set the includeSubpages property: whether or not to include subpages from this domain. + * + * @param includeSubpages the includeSubpages value to set. + * @return the WebKnowledgeSourceBlockedDomain object itself. + */ + @Generated + public WebKnowledgeSourceBlockedDomain setIncludeSubpages(Boolean includeSubpages) { + this.includeSubpages = includeSubpages; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("address", this.address); + jsonWriter.writeBooleanField("includeSubpages", this.includeSubpages); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of WebKnowledgeSourceBlockedDomain from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of WebKnowledgeSourceBlockedDomain if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the WebKnowledgeSourceBlockedDomain. + */ + @Generated + public static WebKnowledgeSourceBlockedDomain fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean addressFound = false; + String address = null; + Boolean includeSubpages = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("address".equals(fieldName)) { + address = reader.getString(); + addressFound = true; + } else if ("includeSubpages".equals(fieldName)) { + includeSubpages = reader.getNullable(JsonReader::getBoolean); + } else { + reader.skipChildren(); + } + } + if (addressFound) { + WebKnowledgeSourceBlockedDomain deserializedWebKnowledgeSourceBlockedDomain + = new WebKnowledgeSourceBlockedDomain(address); + deserializedWebKnowledgeSourceBlockedDomain.includeSubpages = includeSubpages; + + return deserializedWebKnowledgeSourceBlockedDomain; + } + throw new IllegalStateException("Missing required property: address"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java new file mode 100644 index 000000000000..74718d166657 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java @@ -0,0 +1,287 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.List; + +/** + * Parameters for web knowledge source. + */ +@Fluent +public final class WebKnowledgeSourceParameters implements JsonSerializable { + /* + * An explicit identity to use for this knowledge source. + */ + @Generated + private SearchIndexerDataIdentity identity; + + /* + * The ResourceId of the Bing Search resource to use for web results. + */ + @Generated + private String bingResourceId; + + /* + * The language of the web results. + */ + @Generated + private String language; + + /* + * The market of the web results. + */ + @Generated + private String market; + + /* + * The freshness of web results. + */ + @Generated + private String freshness; + + /* + * Domains that are allowed for web results + */ + @Generated + private List allowedDomains; + + /* + * Domains that are blocked from web results + */ + @Generated + private List blockedDomains; + + /** + * Creates an instance of WebKnowledgeSourceParameters class. + */ + @Generated + public WebKnowledgeSourceParameters() { + } + + /** + * Get the identity property: An explicit identity to use for this knowledge source. + * + * @return the identity value. + */ + @Generated + public SearchIndexerDataIdentity getIdentity() { + return this.identity; + } + + /** + * Set the identity property: An explicit identity to use for this knowledge source. + * + * @param identity the identity value to set. + * @return the WebKnowledgeSourceParameters object itself. + */ + @Generated + public WebKnowledgeSourceParameters setIdentity(SearchIndexerDataIdentity identity) { + this.identity = identity; + return this; + } + + /** + * Get the bingResourceId property: The ResourceId of the Bing Search resource to use for web results. + * + * @return the bingResourceId value. + */ + @Generated + public String getBingResourceId() { + return this.bingResourceId; + } + + /** + * Set the bingResourceId property: The ResourceId of the Bing Search resource to use for web results. + * + * @param bingResourceId the bingResourceId value to set. + * @return the WebKnowledgeSourceParameters object itself. + */ + @Generated + public WebKnowledgeSourceParameters setBingResourceId(String bingResourceId) { + this.bingResourceId = bingResourceId; + return this; + } + + /** + * Get the language property: The language of the web results. + * + * @return the language value. + */ + @Generated + public String getLanguage() { + return this.language; + } + + /** + * Set the language property: The language of the web results. + * + * @param language the language value to set. + * @return the WebKnowledgeSourceParameters object itself. + */ + @Generated + public WebKnowledgeSourceParameters setLanguage(String language) { + this.language = language; + return this; + } + + /** + * Get the market property: The market of the web results. + * + * @return the market value. + */ + @Generated + public String getMarket() { + return this.market; + } + + /** + * Set the market property: The market of the web results. + * + * @param market the market value to set. + * @return the WebKnowledgeSourceParameters object itself. + */ + @Generated + public WebKnowledgeSourceParameters setMarket(String market) { + this.market = market; + return this; + } + + /** + * Get the freshness property: The freshness of web results. + * + * @return the freshness value. + */ + @Generated + public String getFreshness() { + return this.freshness; + } + + /** + * Set the freshness property: The freshness of web results. + * + * @param freshness the freshness value to set. + * @return the WebKnowledgeSourceParameters object itself. + */ + @Generated + public WebKnowledgeSourceParameters setFreshness(String freshness) { + this.freshness = freshness; + return this; + } + + /** + * Get the allowedDomains property: Domains that are allowed for web results. + * + * @return the allowedDomains value. + */ + @Generated + public List getAllowedDomains() { + return this.allowedDomains; + } + + /** + * Set the allowedDomains property: Domains that are allowed for web results. + * + * @param allowedDomains the allowedDomains value to set. + * @return the WebKnowledgeSourceParameters object itself. + */ + @Generated + public WebKnowledgeSourceParameters setAllowedDomains(List allowedDomains) { + this.allowedDomains = allowedDomains; + return this; + } + + /** + * Get the blockedDomains property: Domains that are blocked from web results. + * + * @return the blockedDomains value. + */ + @Generated + public List getBlockedDomains() { + return this.blockedDomains; + } + + /** + * Set the blockedDomains property: Domains that are blocked from web results. + * + * @param blockedDomains the blockedDomains value to set. + * @return the WebKnowledgeSourceParameters object itself. + */ + @Generated + public WebKnowledgeSourceParameters setBlockedDomains(List blockedDomains) { + this.blockedDomains = blockedDomains; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeJsonField("identity", this.identity); + jsonWriter.writeStringField("bingResourceId", this.bingResourceId); + jsonWriter.writeStringField("language", this.language); + jsonWriter.writeStringField("market", this.market); + jsonWriter.writeStringField("freshness", this.freshness); + jsonWriter.writeArrayField("allowedDomains", this.allowedDomains, + (writer, element) -> writer.writeJson(element)); + jsonWriter.writeArrayField("blockedDomains", this.blockedDomains, + (writer, element) -> writer.writeJson(element)); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of WebKnowledgeSourceParameters from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of WebKnowledgeSourceParameters if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the WebKnowledgeSourceParameters. + */ + @Generated + public static WebKnowledgeSourceParameters fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + WebKnowledgeSourceParameters deserializedWebKnowledgeSourceParameters = new WebKnowledgeSourceParameters(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("identity".equals(fieldName)) { + deserializedWebKnowledgeSourceParameters.identity = SearchIndexerDataIdentity.fromJson(reader); + } else if ("bingResourceId".equals(fieldName)) { + deserializedWebKnowledgeSourceParameters.bingResourceId = reader.getString(); + } else if ("language".equals(fieldName)) { + deserializedWebKnowledgeSourceParameters.language = reader.getString(); + } else if ("market".equals(fieldName)) { + deserializedWebKnowledgeSourceParameters.market = reader.getString(); + } else if ("freshness".equals(fieldName)) { + deserializedWebKnowledgeSourceParameters.freshness = reader.getString(); + } else if ("allowedDomains".equals(fieldName)) { + List allowedDomains + = reader.readArray(reader1 -> WebKnowledgeSourceAllowedDomain.fromJson(reader1)); + deserializedWebKnowledgeSourceParameters.allowedDomains = allowedDomains; + } else if ("blockedDomains".equals(fieldName)) { + List blockedDomains + = reader.readArray(reader1 -> WebKnowledgeSourceBlockedDomain.fromJson(reader1)); + deserializedWebKnowledgeSourceParameters.blockedDomains = blockedDomains; + } else { + reader.skipChildren(); + } + } + + return deserializedWebKnowledgeSourceParameters; + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java new file mode 100644 index 000000000000..858c196a9fe0 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.indexes.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The ranking adjustment to perform on the web results. + */ +public final class WebKnowledgeSourceRankingAdjustment + extends ExpandableStringEnum { + /** + * Raises the ranking of the chosen domain or subpage so it appears higher in the search results. + */ + @Generated + public static final WebKnowledgeSourceRankingAdjustment BOOST = fromString("boost"); + + /** + * Applies a stronger positive weight than Boost, pushing the selected domain or subpage towards the very top of the + * results. + */ + @Generated + public static final WebKnowledgeSourceRankingAdjustment SUPER_BOOST = fromString("superBoost"); + + /** + * Lowers the ranking of the specified domain or subpage so it shows up further down the results list. + */ + @Generated + public static final WebKnowledgeSourceRankingAdjustment DEMOTE = fromString("demote"); + + /** + * Creates a new instance of WebKnowledgeSourceRankingAdjustment value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public WebKnowledgeSourceRankingAdjustment() { + } + + /** + * Creates or finds a WebKnowledgeSourceRankingAdjustment from its string representation. + * + * @param name a name to look for. + * @return the corresponding WebKnowledgeSourceRankingAdjustment. + */ + @Generated + public static WebKnowledgeSourceRankingAdjustment fromString(String name) { + return fromString(name, WebKnowledgeSourceRankingAdjustment.class); + } + + /** + * Gets known WebKnowledgeSourceRankingAdjustment values. + * + * @return known WebKnowledgeSourceRankingAdjustment values. + */ + @Generated + public static Collection values() { + return values(WebKnowledgeSourceRankingAdjustment.class); + } +} diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java index 432f7a6ebe55..42218de14c0f 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java @@ -16,14 +16,17 @@ import com.azure.search.documents.indexes.models.KnowledgeAgent; import com.azure.search.documents.indexes.models.KnowledgeAgentAzureOpenAIModel; import com.azure.search.documents.indexes.models.KnowledgeAgentModel; -import com.azure.search.documents.indexes.models.KnowledgeAgentTargetIndex; +import com.azure.search.documents.indexes.models.KnowledgeSourceReference; import com.azure.search.documents.indexes.models.SearchIndex; +import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSource; +import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSourceParameters; import com.azure.search.documents.indexes.models.SemanticConfiguration; import com.azure.search.documents.indexes.models.SemanticField; import com.azure.search.documents.indexes.models.SemanticPrioritizedFields; import com.azure.search.documents.indexes.models.SemanticSearch; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -32,7 +35,6 @@ import java.io.UncheckedIOException; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import static com.azure.search.documents.TestHelpers.HOTEL_INDEX_NAME; import static com.azure.search.documents.TestHelpers.loadResource; @@ -43,16 +45,17 @@ import static org.junit.jupiter.api.Assertions.assertThrows; @Execution(ExecutionMode.SAME_THREAD) +@Disabled("Disabled until the service is available.") public class KnowledgeAgentTests extends SearchTestBase { - + private static final String HOTEL_KNOWLEDGE_SOURCE_NAME = "hotel-knowledge-source"; private static final List KNOWLEDGE_AGENT_MODELS = Collections.singletonList(new KnowledgeAgentAzureOpenAIModel( new AzureOpenAIVectorizerParameters().setModelName(AzureOpenAIModelName.GPT4O) .setDeploymentName("gpt-35-turbo") .setApiKey(OPENAI_API_KEY) .setResourceUrl(OPENAI_API_ENDPOINT))); - private static final List KNOWLEDGE_AGENT_TARGET_INDEX - = Collections.singletonList(new KnowledgeAgentTargetIndex(HOTEL_INDEX_NAME)); + private static final List KNOWLEDGE_SOURCE_REFERENCES + = Collections.singletonList(new KnowledgeSourceReference(HOTEL_KNOWLEDGE_SOURCE_NAME)); private static SearchIndexClient searchIndexClient; @@ -66,6 +69,8 @@ public static void setupClass() { } searchIndexClient = setupIndex(); + searchIndexClient.createKnowledgeSource(new SearchIndexKnowledgeSource(HOTEL_KNOWLEDGE_SOURCE_NAME, + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME))); waitForIndexing(); @@ -75,12 +80,13 @@ public static void setupClass() { protected static void cleanupClass() { // Clean up any resources after all tests. if (TEST_MODE != TestMode.PLAYBACK) { + // Delete the knowledge source created for the tests. + searchIndexClient.deleteKnowledgeSource("hotel-knowledge-source", null, null); + // list all remaining knowledge agents and delete them - List knowledgeAgents - = searchIndexClient.listKnowledgeAgents().stream().collect(Collectors.toList()); - for (KnowledgeAgent knowledgeAgent : knowledgeAgents) { - searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName(), null, null); - } + searchIndexClient.listKnowledgeAgents() + .forEach( + knowledgeAgent -> searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName(), null, null)); searchIndexClient.deleteIndex(HOTEL_INDEX_NAME); @@ -97,7 +103,7 @@ public void testCreateKnowledgeAgent() { // Test creating a knowledge agent. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent - = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_AGENT_TARGET_INDEX); + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); } @@ -107,7 +113,7 @@ public void testGetKnowledgeAgent() { SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent - = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_AGENT_TARGET_INDEX); + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); KnowledgeAgent retrieved = searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName()); assertEquals(knowledgeAgent.getName(), retrieved.getName()); @@ -119,14 +125,13 @@ public void testListKnowledgeAgents() { SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); long currentCount = searchIndexClient.listKnowledgeAgents().stream().count(); KnowledgeAgent knowledgeAgent - = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_AGENT_TARGET_INDEX); + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); KnowledgeAgent knowledgeAgent2 - = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_AGENT_TARGET_INDEX); + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); searchIndexClient.createKnowledgeAgent(knowledgeAgent2); - List knowledgeAgents - = searchIndexClient.listKnowledgeAgents().stream().collect(Collectors.toList()); - assertEquals(2 + currentCount, knowledgeAgents.size()); + long knowledgeAgentCount = searchIndexClient.listKnowledgeAgents().stream().count(); + assertEquals(2 + currentCount, knowledgeAgentCount); } @Test @@ -134,7 +139,7 @@ public void testDeleteKnowledgeAgent() { // Test deleting a knowledge agent. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent - = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_AGENT_TARGET_INDEX); + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); waitForIndexing(); assertNotNull(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())); @@ -147,7 +152,7 @@ public void testUpdateKnowledgeAgent() { // Test updating a knowledge agent. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent - = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_AGENT_TARGET_INDEX); + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); String newDescription = "Updated description"; knowledgeAgent.setDescription(newDescription); @@ -181,9 +186,7 @@ private static SearchIndexClient setupIndex() { searchIndexClient.createOrUpdateIndex( TestHelpers.createTestIndex(HOTEL_INDEX_NAME, baseIndex).setSemanticSearch(semanticSearch)); - if (HOTELS_DATA_JSON != null) { - uploadDocumentsJson(searchIndexClient.getSearchClient(HOTEL_INDEX_NAME), HOTELS_DATA_JSON); - } + uploadDocumentsJson(searchIndexClient.getSearchClient(HOTEL_INDEX_NAME), HOTELS_DATA_JSON); return searchIndexClient; } catch (IOException ex) { diff --git a/sdk/search/azure-search-documents/swagger/README.md b/sdk/search/azure-search-documents/swagger/README.md index 6d12b968e4a6..817b0a7f6d23 100644 --- a/sdk/search/azure-search-documents/swagger/README.md +++ b/sdk/search/azure-search-documents/swagger/README.md @@ -478,42 +478,3 @@ directive: $.find(p => p.name === "speller")["x-ms-enum"].name = "QuerySpellerType"; ``` -### Rename `AI Studio` to `AI Foundry` -```yaml -directive: - - from: swagger-document - where: $.definitions.AIStudioModelCatalogName - transform: $["x-ms-enum"].name = "AIFoundryModelCatalogName"; -``` - -```yaml -directive: - - from: swagger-document - where: $.definitions.AMLVectorizer - transform: $.description = $.description.replace("Azure AI Studio", "Azure AI Foundry"); -``` - -```yaml -directive: - - from: swagger-document - where: $.definitions.AMLParameters.properties.modelName - transform: $.description = $.description.replace("Azure AI Studio", "Azure AI Foundry"); -``` - -```yaml -directive: - - from: swagger-document - where: $.definitions.AIStudioModelCatalogName - transform: $.description = $.description.replace("Azure AI Studio", "Azure AI Foundry"); -``` - -```yaml -directive: - - from: swagger-document - where: $.definitions.VectorSearchVectorizerKind - transform: > - $["x-ms-enum"].values = $["x-ms-enum"].values.map((v) => ({ - ...v, - description: v.description.replace("Azure AI Studio", "Azure AI Foundry"), - })); -``` From d4a26fde2266688060a24e1da5a03beed441f4fd Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:18:38 -0400 Subject: [PATCH 03/12] Regen knowledgeagent --- .../azure-search-documents/CHANGELOG.md | 8 + sdk/search/azure-search-documents/pom.xml | 4 +- .../documents/SearchServiceVersion.java | 2 +- .../models/KnowledgeAgentActivityRecord.java | 55 +++- ...wledgeAgentAzureBlobActivityArguments.java | 96 +++++++ ...KnowledgeAgentAzureBlobActivityRecord.java | 197 ++++++++++++++ .../KnowledgeAgentAzureBlobReference.java | 180 +++++++++++++ .../agents/models/KnowledgeAgentMessage.java | 53 ++-- ...entModelAnswerSynthesisActivityRecord.java | 179 +++++++++++++ ...AgentModelQueryPlanningActivityRecord.java | 38 +-- .../models/KnowledgeAgentReference.java | 79 +++++- ...KnowledgeAgentRetrievalActivityRecord.java | 249 ++++++++++++++++++ .../KnowledgeAgentRetrievalRequest.java | 30 +-- ...edgeAgentSearchIndexActivityArguments.java | 127 +++++++++ ...owledgeAgentSearchIndexActivityRecord.java | 197 ++++++++++++++ .../KnowledgeAgentSearchIndexReference.java | 180 +++++++++++++ ...geAgentSemanticRerankerActivityRecord.java | 146 ++++++++++ .../KnowledgeAgentWebActivityArguments.java | 126 +++++++++ .../KnowledgeAgentWebActivityRecord.java | 196 ++++++++++++++ .../models/KnowledgeAgentWebReference.java | 180 +++++++++++++ .../agents/models/KnowledgeSourceKind.java | 65 +++++ .../agents/models/KnowledgeSourceParams.java | 142 ++++++++++ .../SearchIndexKnowledgeSourceParams.java | 131 +++++++++ .../models/WebKnowledgeSourceParams.java | 131 +++++++++ 24 files changed, 2708 insertions(+), 83 deletions(-) create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobActivityArguments.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobActivityRecord.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobReference.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelAnswerSynthesisActivityRecord.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityArguments.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityRecord.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexReference.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSemanticRerankerActivityRecord.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceParams.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/SearchIndexKnowledgeSourceParams.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java diff --git a/sdk/search/azure-search-documents/CHANGELOG.md b/sdk/search/azure-search-documents/CHANGELOG.md index b9355733f176..57ff445f637d 100644 --- a/sdk/search/azure-search-documents/CHANGELOG.md +++ b/sdk/search/azure-search-documents/CHANGELOG.md @@ -4,8 +4,16 @@ ### Features Added +- Support for `2025-08-01-Preview` service version. + - Added support for Knowledge Agent knowledge sources. + - Added support for Knowledge Agent answer synthesis. + - Added `VectorFilterMode.STRICT_POST_FILTER`. + ### Breaking Changes +- Dropped support for `2025-05-01-Preview` service version. + - Dropped support for Knowledge Agent target index. Use knowledge sources instead. + ### Bugs Fixed ### Other Changes diff --git a/sdk/search/azure-search-documents/pom.xml b/sdk/search/azure-search-documents/pom.xml index bfbbc5d4a561..290eae6373c5 100644 --- a/sdk/search/azure-search-documents/pom.xml +++ b/sdk/search/azure-search-documents/pom.xml @@ -24,8 +24,8 @@ UTF-8 - 0.46 - 0.40 + 0.42 + 0.35 --add-exports com.azure.core/com.azure.core.implementation.http=ALL-UNNAMED diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java index e33367e2e280..d74ba368209c 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java @@ -25,7 +25,7 @@ public enum SearchServiceVersion implements ServiceVersion { V2024_07_01("2024-07-01"), /** - * {@code 2024-11-01-preview} service version. + * {@code 2025-05-01-preview} service version. */ V2025_05_01_PREVIEW("2025-05-01-preview"); diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java index df614e32f68b..f2a23c197c82 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java @@ -6,8 +6,8 @@ package com.azure.search.documents.agents.models; +import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; @@ -17,7 +17,7 @@ /** * Base type for activity records. */ -@Immutable +@Fluent public class KnowledgeAgentActivityRecord implements JsonSerializable { /* * The type of the activity record. @@ -31,6 +31,12 @@ public class KnowledgeAgentActivityRecord implements JsonSerializable { + /* + * The search string used to query blob contents. + */ + @Generated + private String search; + + /** + * Creates an instance of KnowledgeAgentAzureBlobActivityArguments class. + */ + @Generated + public KnowledgeAgentAzureBlobActivityArguments() { + } + + /** + * Get the search property: The search string used to query blob contents. + * + * @return the search value. + */ + @Generated + public String getSearch() { + return this.search; + } + + /** + * Set the search property: The search string used to query blob contents. + * + * @param search the search value to set. + * @return the KnowledgeAgentAzureBlobActivityArguments object itself. + */ + @Generated + public KnowledgeAgentAzureBlobActivityArguments setSearch(String search) { + this.search = search; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("search", this.search); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentAzureBlobActivityArguments from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentAzureBlobActivityArguments if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the KnowledgeAgentAzureBlobActivityArguments. + */ + @Generated + public static KnowledgeAgentAzureBlobActivityArguments fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + KnowledgeAgentAzureBlobActivityArguments deserializedKnowledgeAgentAzureBlobActivityArguments + = new KnowledgeAgentAzureBlobActivityArguments(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("search".equals(fieldName)) { + deserializedKnowledgeAgentAzureBlobActivityArguments.search = reader.getString(); + } else { + reader.skipChildren(); + } + } + + return deserializedKnowledgeAgentAzureBlobActivityArguments; + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobActivityRecord.java new file mode 100644 index 000000000000..ecf325003f93 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobActivityRecord.java @@ -0,0 +1,197 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.CoreUtils; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Represents a azure blob retrieval activity record. + */ +@Fluent +public final class KnowledgeAgentAzureBlobActivityRecord extends KnowledgeAgentRetrievalActivityRecord { + /* + * The type of the activity record. + */ + @Generated + private String type = "azureBlob"; + + /* + * The azure blob arguments for the retrieval activity. + */ + @Generated + private KnowledgeAgentAzureBlobActivityArguments azureBlobArguments; + + /** + * Creates an instance of KnowledgeAgentAzureBlobActivityRecord class. + * + * @param id the id value to set. + */ + @Generated + public KnowledgeAgentAzureBlobActivityRecord(int id) { + super(id); + } + + /** + * Get the type property: The type of the activity record. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the azureBlobArguments property: The azure blob arguments for the retrieval activity. + * + * @return the azureBlobArguments value. + */ + @Generated + public KnowledgeAgentAzureBlobActivityArguments getAzureBlobArguments() { + return this.azureBlobArguments; + } + + /** + * Set the azureBlobArguments property: The azure blob arguments for the retrieval activity. + * + * @param azureBlobArguments the azureBlobArguments value to set. + * @return the KnowledgeAgentAzureBlobActivityRecord object itself. + */ + @Generated + public KnowledgeAgentAzureBlobActivityRecord + setAzureBlobArguments(KnowledgeAgentAzureBlobActivityArguments azureBlobArguments) { + this.azureBlobArguments = azureBlobArguments; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentAzureBlobActivityRecord setKnowledgeSourceName(String knowledgeSourceName) { + super.setKnowledgeSourceName(knowledgeSourceName); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentAzureBlobActivityRecord setQueryTime(OffsetDateTime queryTime) { + super.setQueryTime(queryTime); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentAzureBlobActivityRecord setCount(Integer count) { + super.setCount(count); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentAzureBlobActivityRecord setElapsedMs(Integer elapsedMs) { + super.setElapsedMs(elapsedMs); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeIntField("id", getId()); + jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); + jsonWriter.writeStringField("knowledgeSourceName", getKnowledgeSourceName()); + jsonWriter.writeStringField("queryTime", + getQueryTime() == null ? null : DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(getQueryTime())); + jsonWriter.writeNumberField("count", getCount()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeJsonField("azureBlobArguments", this.azureBlobArguments); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentAzureBlobActivityRecord from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentAzureBlobActivityRecord if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentAzureBlobActivityRecord. + */ + @Generated + public static KnowledgeAgentAzureBlobActivityRecord fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + int id = 0; + Integer elapsedMs = null; + String knowledgeSourceName = null; + OffsetDateTime queryTime = null; + Integer count = null; + String type = "azureBlob"; + KnowledgeAgentAzureBlobActivityArguments azureBlobArguments = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getInt(); + idFound = true; + } else if ("elapsedMs".equals(fieldName)) { + elapsedMs = reader.getNullable(JsonReader::getInt); + } else if ("knowledgeSourceName".equals(fieldName)) { + knowledgeSourceName = reader.getString(); + } else if ("queryTime".equals(fieldName)) { + queryTime = reader + .getNullable(nonNullReader -> CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); + } else if ("count".equals(fieldName)) { + count = reader.getNullable(JsonReader::getInt); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("azureBlobArguments".equals(fieldName)) { + azureBlobArguments = KnowledgeAgentAzureBlobActivityArguments.fromJson(reader); + } else { + reader.skipChildren(); + } + } + if (idFound) { + KnowledgeAgentAzureBlobActivityRecord deserializedKnowledgeAgentAzureBlobActivityRecord + = new KnowledgeAgentAzureBlobActivityRecord(id); + deserializedKnowledgeAgentAzureBlobActivityRecord.setElapsedMs(elapsedMs); + deserializedKnowledgeAgentAzureBlobActivityRecord.setKnowledgeSourceName(knowledgeSourceName); + deserializedKnowledgeAgentAzureBlobActivityRecord.setQueryTime(queryTime); + deserializedKnowledgeAgentAzureBlobActivityRecord.setCount(count); + deserializedKnowledgeAgentAzureBlobActivityRecord.type = type; + deserializedKnowledgeAgentAzureBlobActivityRecord.azureBlobArguments = azureBlobArguments; + + return deserializedKnowledgeAgentAzureBlobActivityRecord; + } + throw new IllegalStateException("Missing required property: id"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobReference.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobReference.java new file mode 100644 index 000000000000..a511f405c2b2 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentAzureBlobReference.java @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Represents an Azure Blob Storage document reference. + */ +@Fluent +public final class KnowledgeAgentAzureBlobReference extends KnowledgeAgentReference { + /* + * The type of the reference. + */ + @Generated + private String type = "azureBlob"; + + /* + * The blob URL for the reference. + */ + @Generated + private String blobUrl; + + /** + * Creates an instance of KnowledgeAgentAzureBlobReference class. + * + * @param id the id value to set. + * @param activitySource the activitySource value to set. + */ + @Generated + public KnowledgeAgentAzureBlobReference(String id, int activitySource) { + super(id, activitySource); + } + + /** + * Get the type property: The type of the reference. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the blobUrl property: The blob URL for the reference. + * + * @return the blobUrl value. + */ + @Generated + public String getBlobUrl() { + return this.blobUrl; + } + + /** + * Set the blobUrl property: The blob URL for the reference. + * + * @param blobUrl the blobUrl value to set. + * @return the KnowledgeAgentAzureBlobReference object itself. + */ + @Generated + public KnowledgeAgentAzureBlobReference setBlobUrl(String blobUrl) { + this.blobUrl = blobUrl; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentAzureBlobReference setSourceData(Map sourceData) { + super.setSourceData(sourceData); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentAzureBlobReference setRerankerScore(Float rerankerScore) { + super.setRerankerScore(rerankerScore); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", getId()); + jsonWriter.writeIntField("activitySource", getActivitySource()); + jsonWriter.writeMapField("sourceData", getSourceData(), (writer, element) -> writer.writeUntyped(element)); + jsonWriter.writeNumberField("rerankerScore", getRerankerScore()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("blobUrl", this.blobUrl); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentAzureBlobReference from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentAzureBlobReference if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentAzureBlobReference. + */ + @Generated + public static KnowledgeAgentAzureBlobReference fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + String id = null; + boolean activitySourceFound = false; + int activitySource = 0; + Map sourceData = null; + Float rerankerScore = null; + String type = "azureBlob"; + String blobUrl = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getString(); + idFound = true; + } else if ("activitySource".equals(fieldName)) { + activitySource = reader.getInt(); + activitySourceFound = true; + } else if ("sourceData".equals(fieldName)) { + sourceData = reader.readMap(reader1 -> reader1.readUntyped()); + } else if ("rerankerScore".equals(fieldName)) { + rerankerScore = reader.getNullable(JsonReader::getFloat); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("blobUrl".equals(fieldName)) { + blobUrl = reader.getString(); + } else { + reader.skipChildren(); + } + } + if (idFound && activitySourceFound) { + KnowledgeAgentAzureBlobReference deserializedKnowledgeAgentAzureBlobReference + = new KnowledgeAgentAzureBlobReference(id, activitySource); + deserializedKnowledgeAgentAzureBlobReference.setSourceData(sourceData); + deserializedKnowledgeAgentAzureBlobReference.setRerankerScore(rerankerScore); + deserializedKnowledgeAgentAzureBlobReference.type = type; + deserializedKnowledgeAgentAzureBlobReference.blobUrl = blobUrl; + + return deserializedKnowledgeAgentAzureBlobReference; + } + List missingProperties = new ArrayList<>(); + if (!idFound) { + missingProperties.add("id"); + } + if (!activitySourceFound) { + missingProperties.add("activitySource"); + } + + throw new IllegalStateException( + "Missing required property/properties: " + String.join(", ", missingProperties)); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentMessage.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentMessage.java index 99c2cd27a6c2..55e964519b91 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentMessage.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentMessage.java @@ -6,26 +6,25 @@ package com.azure.search.documents.agents.models; +import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; import java.io.IOException; -import java.util.ArrayList; import java.util.List; /** * The natural language message style object. */ -@Immutable +@Fluent public final class KnowledgeAgentMessage implements JsonSerializable { /* * The role of the tool response. */ @Generated - private final String role; + private String role; /* * The content property. @@ -36,12 +35,10 @@ public final class KnowledgeAgentMessage implements JsonSerializable content) { - this.role = role; + public KnowledgeAgentMessage(List content) { this.content = content; } @@ -55,6 +52,18 @@ public String getRole() { return this.role; } + /** + * Set the role property: The role of the tool response. + * + * @param role the role value to set. + * @return the KnowledgeAgentMessage object itself. + */ + @Generated + public KnowledgeAgentMessage setRole(String role) { + this.role = role; + return this; + } + /** * Get the content property: The content property. * @@ -72,8 +81,8 @@ public List getContent() { @Override public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); - jsonWriter.writeStringField("role", this.role); jsonWriter.writeArrayField("content", this.content, (writer, element) -> writer.writeJson(element)); + jsonWriter.writeStringField("role", this.role); return jsonWriter.writeEndObject(); } @@ -89,37 +98,29 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { @Generated public static KnowledgeAgentMessage fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { - boolean roleFound = false; - String role = null; boolean contentFound = false; List content = null; + String role = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); - if ("role".equals(fieldName)) { - role = reader.getString(); - roleFound = true; - } else if ("content".equals(fieldName)) { + if ("content".equals(fieldName)) { content = reader.readArray(reader1 -> KnowledgeAgentMessageContent.fromJson(reader1)); contentFound = true; + } else if ("role".equals(fieldName)) { + role = reader.getString(); } else { reader.skipChildren(); } } - if (roleFound && contentFound) { - return new KnowledgeAgentMessage(role, content); - } - List missingProperties = new ArrayList<>(); - if (!roleFound) { - missingProperties.add("role"); - } - if (!contentFound) { - missingProperties.add("content"); - } + if (contentFound) { + KnowledgeAgentMessage deserializedKnowledgeAgentMessage = new KnowledgeAgentMessage(content); + deserializedKnowledgeAgentMessage.role = role; - throw new IllegalStateException( - "Missing required property/properties: " + String.join(", ", missingProperties)); + return deserializedKnowledgeAgentMessage; + } + throw new IllegalStateException("Missing required property: content"); }); } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelAnswerSynthesisActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelAnswerSynthesisActivityRecord.java new file mode 100644 index 000000000000..759e853348cf --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelAnswerSynthesisActivityRecord.java @@ -0,0 +1,179 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Represents an LLM answer synthesis activity record. + */ +@Fluent +public final class KnowledgeAgentModelAnswerSynthesisActivityRecord extends KnowledgeAgentActivityRecord { + /* + * The type of the activity record. + */ + @Generated + private String type = "modelAnswerSynthesis"; + + /* + * The number of input tokens for the LLM answer synthesis activity. + */ + @Generated + private Integer inputTokens; + + /* + * The number of output tokens for the LLM answer synthesis activity. + */ + @Generated + private Integer outputTokens; + + /** + * Creates an instance of KnowledgeAgentModelAnswerSynthesisActivityRecord class. + * + * @param id the id value to set. + */ + @Generated + public KnowledgeAgentModelAnswerSynthesisActivityRecord(int id) { + super(id); + } + + /** + * Get the type property: The type of the activity record. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the inputTokens property: The number of input tokens for the LLM answer synthesis activity. + * + * @return the inputTokens value. + */ + @Generated + public Integer getInputTokens() { + return this.inputTokens; + } + + /** + * Set the inputTokens property: The number of input tokens for the LLM answer synthesis activity. + * + * @param inputTokens the inputTokens value to set. + * @return the KnowledgeAgentModelAnswerSynthesisActivityRecord object itself. + */ + @Generated + public KnowledgeAgentModelAnswerSynthesisActivityRecord setInputTokens(Integer inputTokens) { + this.inputTokens = inputTokens; + return this; + } + + /** + * Get the outputTokens property: The number of output tokens for the LLM answer synthesis activity. + * + * @return the outputTokens value. + */ + @Generated + public Integer getOutputTokens() { + return this.outputTokens; + } + + /** + * Set the outputTokens property: The number of output tokens for the LLM answer synthesis activity. + * + * @param outputTokens the outputTokens value to set. + * @return the KnowledgeAgentModelAnswerSynthesisActivityRecord object itself. + */ + @Generated + public KnowledgeAgentModelAnswerSynthesisActivityRecord setOutputTokens(Integer outputTokens) { + this.outputTokens = outputTokens; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentModelAnswerSynthesisActivityRecord setElapsedMs(Integer elapsedMs) { + super.setElapsedMs(elapsedMs); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeIntField("id", getId()); + jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeNumberField("inputTokens", this.inputTokens); + jsonWriter.writeNumberField("outputTokens", this.outputTokens); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentModelAnswerSynthesisActivityRecord from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentModelAnswerSynthesisActivityRecord if the JsonReader was pointing to an + * instance of it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentModelAnswerSynthesisActivityRecord. + */ + @Generated + public static KnowledgeAgentModelAnswerSynthesisActivityRecord fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + int id = 0; + Integer elapsedMs = null; + String type = "modelAnswerSynthesis"; + Integer inputTokens = null; + Integer outputTokens = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getInt(); + idFound = true; + } else if ("elapsedMs".equals(fieldName)) { + elapsedMs = reader.getNullable(JsonReader::getInt); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("inputTokens".equals(fieldName)) { + inputTokens = reader.getNullable(JsonReader::getInt); + } else if ("outputTokens".equals(fieldName)) { + outputTokens = reader.getNullable(JsonReader::getInt); + } else { + reader.skipChildren(); + } + } + if (idFound) { + KnowledgeAgentModelAnswerSynthesisActivityRecord deserializedKnowledgeAgentModelAnswerSynthesisActivityRecord + = new KnowledgeAgentModelAnswerSynthesisActivityRecord(id); + deserializedKnowledgeAgentModelAnswerSynthesisActivityRecord.setElapsedMs(elapsedMs); + deserializedKnowledgeAgentModelAnswerSynthesisActivityRecord.type = type; + deserializedKnowledgeAgentModelAnswerSynthesisActivityRecord.inputTokens = inputTokens; + deserializedKnowledgeAgentModelAnswerSynthesisActivityRecord.outputTokens = outputTokens; + + return deserializedKnowledgeAgentModelAnswerSynthesisActivityRecord; + } + throw new IllegalStateException("Missing required property: id"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelQueryPlanningActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelQueryPlanningActivityRecord.java index 3e11de4144bd..3b4bb27b7cc4 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelQueryPlanningActivityRecord.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentModelQueryPlanningActivityRecord.java @@ -22,7 +22,7 @@ public final class KnowledgeAgentModelQueryPlanningActivityRecord extends Knowle * The type of the activity record. */ @Generated - private String type = "ModelQueryPlanning"; + private String type = "modelQueryPlanning"; /* * The number of input tokens for the LLM query planning activity. @@ -36,12 +36,6 @@ public final class KnowledgeAgentModelQueryPlanningActivityRecord extends Knowle @Generated private Integer outputTokens; - /* - * The elapsed time in milliseconds for the model activity. - */ - @Generated - private Integer elapsedMs; - /** * Creates an instance of KnowledgeAgentModelQueryPlanningActivityRecord class. * @@ -108,24 +102,12 @@ public KnowledgeAgentModelQueryPlanningActivityRecord setOutputTokens(Integer ou } /** - * Get the elapsedMs property: The elapsed time in milliseconds for the model activity. - * - * @return the elapsedMs value. - */ - @Generated - public Integer getElapsedMs() { - return this.elapsedMs; - } - - /** - * Set the elapsedMs property: The elapsed time in milliseconds for the model activity. - * - * @param elapsedMs the elapsedMs value to set. - * @return the KnowledgeAgentModelQueryPlanningActivityRecord object itself. + * {@inheritDoc} */ @Generated + @Override public KnowledgeAgentModelQueryPlanningActivityRecord setElapsedMs(Integer elapsedMs) { - this.elapsedMs = elapsedMs; + super.setElapsedMs(elapsedMs); return this; } @@ -137,10 +119,10 @@ public KnowledgeAgentModelQueryPlanningActivityRecord setElapsedMs(Integer elaps public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStartObject(); jsonWriter.writeIntField("id", getId()); + jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); jsonWriter.writeStringField("type", this.type); jsonWriter.writeNumberField("inputTokens", this.inputTokens); jsonWriter.writeNumberField("outputTokens", this.outputTokens); - jsonWriter.writeNumberField("elapsedMs", this.elapsedMs); return jsonWriter.writeEndObject(); } @@ -158,10 +140,10 @@ public static KnowledgeAgentModelQueryPlanningActivityRecord fromJson(JsonReader return jsonReader.readObject(reader -> { boolean idFound = false; int id = 0; - String type = "ModelQueryPlanning"; + Integer elapsedMs = null; + String type = "modelQueryPlanning"; Integer inputTokens = null; Integer outputTokens = null; - Integer elapsedMs = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); @@ -169,14 +151,14 @@ public static KnowledgeAgentModelQueryPlanningActivityRecord fromJson(JsonReader if ("id".equals(fieldName)) { id = reader.getInt(); idFound = true; + } else if ("elapsedMs".equals(fieldName)) { + elapsedMs = reader.getNullable(JsonReader::getInt); } else if ("type".equals(fieldName)) { type = reader.getString(); } else if ("inputTokens".equals(fieldName)) { inputTokens = reader.getNullable(JsonReader::getInt); } else if ("outputTokens".equals(fieldName)) { outputTokens = reader.getNullable(JsonReader::getInt); - } else if ("elapsedMs".equals(fieldName)) { - elapsedMs = reader.getNullable(JsonReader::getInt); } else { reader.skipChildren(); } @@ -184,10 +166,10 @@ public static KnowledgeAgentModelQueryPlanningActivityRecord fromJson(JsonReader if (idFound) { KnowledgeAgentModelQueryPlanningActivityRecord deserializedKnowledgeAgentModelQueryPlanningActivityRecord = new KnowledgeAgentModelQueryPlanningActivityRecord(id); + deserializedKnowledgeAgentModelQueryPlanningActivityRecord.setElapsedMs(elapsedMs); deserializedKnowledgeAgentModelQueryPlanningActivityRecord.type = type; deserializedKnowledgeAgentModelQueryPlanningActivityRecord.inputTokens = inputTokens; deserializedKnowledgeAgentModelQueryPlanningActivityRecord.outputTokens = outputTokens; - deserializedKnowledgeAgentModelQueryPlanningActivityRecord.elapsedMs = elapsedMs; return deserializedKnowledgeAgentModelQueryPlanningActivityRecord; } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java index 50fc40610085..49a9ef4cd81c 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java @@ -6,8 +6,8 @@ package com.azure.search.documents.agents.models; +import com.azure.core.annotation.Fluent; import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; @@ -15,11 +15,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Base type for references. */ -@Immutable +@Fluent public class KnowledgeAgentReference implements JsonSerializable { /* * The type of the reference. @@ -39,6 +40,18 @@ public class KnowledgeAgentReference implements JsonSerializable + */ + @Generated + private Map sourceData; + + /* + * The reranker score for the document reference. + */ + @Generated + private Float rerankerScore; + /** * Creates an instance of KnowledgeAgentReference class. * @@ -81,6 +94,50 @@ public int getActivitySource() { return this.activitySource; } + /** + * Get the sourceData property: Dictionary of <any>. + * + * @return the sourceData value. + */ + @Generated + public Map getSourceData() { + return this.sourceData; + } + + /** + * Set the sourceData property: Dictionary of <any>. + * + * @param sourceData the sourceData value to set. + * @return the KnowledgeAgentReference object itself. + */ + @Generated + public KnowledgeAgentReference setSourceData(Map sourceData) { + this.sourceData = sourceData; + return this; + } + + /** + * Get the rerankerScore property: The reranker score for the document reference. + * + * @return the rerankerScore value. + */ + @Generated + public Float getRerankerScore() { + return this.rerankerScore; + } + + /** + * Set the rerankerScore property: The reranker score for the document reference. + * + * @param rerankerScore the rerankerScore value to set. + * @return the KnowledgeAgentReference object itself. + */ + @Generated + public KnowledgeAgentReference setRerankerScore(Float rerankerScore) { + this.rerankerScore = rerankerScore; + return this; + } + /** * {@inheritDoc} */ @@ -91,6 +148,8 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStringField("id", this.id); jsonWriter.writeIntField("activitySource", this.activitySource); jsonWriter.writeStringField("type", this.type); + jsonWriter.writeMapField("sourceData", this.sourceData, (writer, element) -> writer.writeUntyped(element)); + jsonWriter.writeNumberField("rerankerScore", this.rerankerScore); return jsonWriter.writeEndObject(); } @@ -120,8 +179,12 @@ public static KnowledgeAgentReference fromJson(JsonReader jsonReader) throws IOE } } // Use the discriminator value to determine which subtype should be deserialized. - if ("AzureSearchDoc".equals(discriminatorValue)) { - return KnowledgeAgentAzureSearchDocReference.fromJson(readerToUse.reset()); + if ("searchIndex".equals(discriminatorValue)) { + return KnowledgeAgentSearchIndexReference.fromJson(readerToUse.reset()); + } else if ("azureBlob".equals(discriminatorValue)) { + return KnowledgeAgentAzureBlobReference.fromJson(readerToUse.reset()); + } else if ("web".equals(discriminatorValue)) { + return KnowledgeAgentWebReference.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } @@ -137,6 +200,8 @@ static KnowledgeAgentReference fromJsonKnownDiscriminator(JsonReader jsonReader) boolean activitySourceFound = false; int activitySource = 0; String type = null; + Map sourceData = null; + Float rerankerScore = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); @@ -149,6 +214,10 @@ static KnowledgeAgentReference fromJsonKnownDiscriminator(JsonReader jsonReader) activitySourceFound = true; } else if ("type".equals(fieldName)) { type = reader.getString(); + } else if ("sourceData".equals(fieldName)) { + sourceData = reader.readMap(reader1 -> reader1.readUntyped()); + } else if ("rerankerScore".equals(fieldName)) { + rerankerScore = reader.getNullable(JsonReader::getFloat); } else { reader.skipChildren(); } @@ -157,6 +226,8 @@ static KnowledgeAgentReference fromJsonKnownDiscriminator(JsonReader jsonReader) KnowledgeAgentReference deserializedKnowledgeAgentReference = new KnowledgeAgentReference(id, activitySource); deserializedKnowledgeAgentReference.type = type; + deserializedKnowledgeAgentReference.sourceData = sourceData; + deserializedKnowledgeAgentReference.rerankerScore = rerankerScore; return deserializedKnowledgeAgentReference; } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java new file mode 100644 index 000000000000..5b9607d1e890 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java @@ -0,0 +1,249 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.CoreUtils; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Represents a retrieval activity record. + */ +@Fluent +public class KnowledgeAgentRetrievalActivityRecord extends KnowledgeAgentActivityRecord { + /* + * The type of the activity record. + */ + @Generated + private String type = "KnowledgeAgentRetrievalActivityRecord"; + + /* + * The knowledge source for the retrieval activity. + */ + @Generated + private String knowledgeSourceName; + + /* + * The query time for this retrieval activity. + */ + @Generated + private OffsetDateTime queryTime; + + /* + * The count of documents retrieved that were sufficiently relevant to pass the reranker threshold. + */ + @Generated + private Integer count; + + /** + * Creates an instance of KnowledgeAgentRetrievalActivityRecord class. + * + * @param id the id value to set. + */ + @Generated + public KnowledgeAgentRetrievalActivityRecord(int id) { + super(id); + } + + /** + * Get the type property: The type of the activity record. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the knowledgeSourceName property: The knowledge source for the retrieval activity. + * + * @return the knowledgeSourceName value. + */ + @Generated + public String getKnowledgeSourceName() { + return this.knowledgeSourceName; + } + + /** + * Set the knowledgeSourceName property: The knowledge source for the retrieval activity. + * + * @param knowledgeSourceName the knowledgeSourceName value to set. + * @return the KnowledgeAgentRetrievalActivityRecord object itself. + */ + @Generated + public KnowledgeAgentRetrievalActivityRecord setKnowledgeSourceName(String knowledgeSourceName) { + this.knowledgeSourceName = knowledgeSourceName; + return this; + } + + /** + * Get the queryTime property: The query time for this retrieval activity. + * + * @return the queryTime value. + */ + @Generated + public OffsetDateTime getQueryTime() { + return this.queryTime; + } + + /** + * Set the queryTime property: The query time for this retrieval activity. + * + * @param queryTime the queryTime value to set. + * @return the KnowledgeAgentRetrievalActivityRecord object itself. + */ + @Generated + public KnowledgeAgentRetrievalActivityRecord setQueryTime(OffsetDateTime queryTime) { + this.queryTime = queryTime; + return this; + } + + /** + * Get the count property: The count of documents retrieved that were sufficiently relevant to pass the reranker + * threshold. + * + * @return the count value. + */ + @Generated + public Integer getCount() { + return this.count; + } + + /** + * Set the count property: The count of documents retrieved that were sufficiently relevant to pass the reranker + * threshold. + * + * @param count the count value to set. + * @return the KnowledgeAgentRetrievalActivityRecord object itself. + */ + @Generated + public KnowledgeAgentRetrievalActivityRecord setCount(Integer count) { + this.count = count; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentRetrievalActivityRecord setElapsedMs(Integer elapsedMs) { + super.setElapsedMs(elapsedMs); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeIntField("id", getId()); + jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("knowledgeSourceName", this.knowledgeSourceName); + jsonWriter.writeStringField("queryTime", + this.queryTime == null ? null : DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(this.queryTime)); + jsonWriter.writeNumberField("count", this.count); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentRetrievalActivityRecord from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentRetrievalActivityRecord if the JsonReader was pointing to an instance of it, + * or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentRetrievalActivityRecord. + */ + @Generated + public static KnowledgeAgentRetrievalActivityRecord fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + readerToUse.nextToken(); // Prepare for reading + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("type".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("searchIndex".equals(discriminatorValue)) { + return KnowledgeAgentSearchIndexActivityRecord.fromJson(readerToUse.reset()); + } else if ("azureBlob".equals(discriminatorValue)) { + return KnowledgeAgentAzureBlobActivityRecord.fromJson(readerToUse.reset()); + } else if ("web".equals(discriminatorValue)) { + return KnowledgeAgentWebActivityRecord.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static KnowledgeAgentRetrievalActivityRecord fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + int id = 0; + Integer elapsedMs = null; + String type = "KnowledgeAgentRetrievalActivityRecord"; + String knowledgeSourceName = null; + OffsetDateTime queryTime = null; + Integer count = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getInt(); + idFound = true; + } else if ("elapsedMs".equals(fieldName)) { + elapsedMs = reader.getNullable(JsonReader::getInt); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("knowledgeSourceName".equals(fieldName)) { + knowledgeSourceName = reader.getString(); + } else if ("queryTime".equals(fieldName)) { + queryTime = reader + .getNullable(nonNullReader -> CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); + } else if ("count".equals(fieldName)) { + count = reader.getNullable(JsonReader::getInt); + } else { + reader.skipChildren(); + } + } + if (idFound) { + KnowledgeAgentRetrievalActivityRecord deserializedKnowledgeAgentRetrievalActivityRecord + = new KnowledgeAgentRetrievalActivityRecord(id); + deserializedKnowledgeAgentRetrievalActivityRecord.setElapsedMs(elapsedMs); + deserializedKnowledgeAgentRetrievalActivityRecord.type = type; + deserializedKnowledgeAgentRetrievalActivityRecord.knowledgeSourceName = knowledgeSourceName; + deserializedKnowledgeAgentRetrievalActivityRecord.queryTime = queryTime; + deserializedKnowledgeAgentRetrievalActivityRecord.count = count; + + return deserializedKnowledgeAgentRetrievalActivityRecord; + } + throw new IllegalStateException("Missing required property: id"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalRequest.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalRequest.java index 6d70e009f81b..7f9a16367598 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalRequest.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalRequest.java @@ -27,10 +27,10 @@ public final class KnowledgeAgentRetrievalRequest implements JsonSerializable messages; /* - * The targetIndexParams property. + * The knowledgeSourceParams property. */ @Generated - private List targetIndexParams; + private List knowledgeSourceParams; /** * Creates an instance of KnowledgeAgentRetrievalRequest class. @@ -53,24 +53,24 @@ public List getMessages() { } /** - * Get the targetIndexParams property: The targetIndexParams property. + * Get the knowledgeSourceParams property: The knowledgeSourceParams property. * - * @return the targetIndexParams value. + * @return the knowledgeSourceParams value. */ @Generated - public List getTargetIndexParams() { - return this.targetIndexParams; + public List getKnowledgeSourceParams() { + return this.knowledgeSourceParams; } /** - * Set the targetIndexParams property: The targetIndexParams property. + * Set the knowledgeSourceParams property: The knowledgeSourceParams property. * - * @param targetIndexParams the targetIndexParams value to set. + * @param knowledgeSourceParams the knowledgeSourceParams value to set. * @return the KnowledgeAgentRetrievalRequest object itself. */ @Generated - public KnowledgeAgentRetrievalRequest setTargetIndexParams(List targetIndexParams) { - this.targetIndexParams = targetIndexParams; + public KnowledgeAgentRetrievalRequest setKnowledgeSourceParams(List knowledgeSourceParams) { + this.knowledgeSourceParams = knowledgeSourceParams; return this; } @@ -82,7 +82,7 @@ public KnowledgeAgentRetrievalRequest setTargetIndexParams(List writer.writeJson(element)); - jsonWriter.writeArrayField("targetIndexParams", this.targetIndexParams, + jsonWriter.writeArrayField("knowledgeSourceParams", this.knowledgeSourceParams, (writer, element) -> writer.writeJson(element)); return jsonWriter.writeEndObject(); } @@ -101,7 +101,7 @@ public static KnowledgeAgentRetrievalRequest fromJson(JsonReader jsonReader) thr return jsonReader.readObject(reader -> { boolean messagesFound = false; List messages = null; - List targetIndexParams = null; + List knowledgeSourceParams = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); @@ -109,8 +109,8 @@ public static KnowledgeAgentRetrievalRequest fromJson(JsonReader jsonReader) thr if ("messages".equals(fieldName)) { messages = reader.readArray(reader1 -> KnowledgeAgentMessage.fromJson(reader1)); messagesFound = true; - } else if ("targetIndexParams".equals(fieldName)) { - targetIndexParams = reader.readArray(reader1 -> KnowledgeAgentIndexParams.fromJson(reader1)); + } else if ("knowledgeSourceParams".equals(fieldName)) { + knowledgeSourceParams = reader.readArray(reader1 -> KnowledgeSourceParams.fromJson(reader1)); } else { reader.skipChildren(); } @@ -118,7 +118,7 @@ public static KnowledgeAgentRetrievalRequest fromJson(JsonReader jsonReader) thr if (messagesFound) { KnowledgeAgentRetrievalRequest deserializedKnowledgeAgentRetrievalRequest = new KnowledgeAgentRetrievalRequest(messages); - deserializedKnowledgeAgentRetrievalRequest.targetIndexParams = targetIndexParams; + deserializedKnowledgeAgentRetrievalRequest.knowledgeSourceParams = knowledgeSourceParams; return deserializedKnowledgeAgentRetrievalRequest; } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityArguments.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityArguments.java new file mode 100644 index 000000000000..a73abc2b6a41 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityArguments.java @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Represents the arguments the search index retrieval activity was run with. + */ +@Fluent +public final class KnowledgeAgentSearchIndexActivityArguments + implements JsonSerializable { + /* + * The search string used to query the search index. + */ + @Generated + private String search; + + /* + * The filter string. + */ + @Generated + private String filter; + + /** + * Creates an instance of KnowledgeAgentSearchIndexActivityArguments class. + */ + @Generated + public KnowledgeAgentSearchIndexActivityArguments() { + } + + /** + * Get the search property: The search string used to query the search index. + * + * @return the search value. + */ + @Generated + public String getSearch() { + return this.search; + } + + /** + * Set the search property: The search string used to query the search index. + * + * @param search the search value to set. + * @return the KnowledgeAgentSearchIndexActivityArguments object itself. + */ + @Generated + public KnowledgeAgentSearchIndexActivityArguments setSearch(String search) { + this.search = search; + return this; + } + + /** + * Get the filter property: The filter string. + * + * @return the filter value. + */ + @Generated + public String getFilter() { + return this.filter; + } + + /** + * Set the filter property: The filter string. + * + * @param filter the filter value to set. + * @return the KnowledgeAgentSearchIndexActivityArguments object itself. + */ + @Generated + public KnowledgeAgentSearchIndexActivityArguments setFilter(String filter) { + this.filter = filter; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("search", this.search); + jsonWriter.writeStringField("filter", this.filter); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentSearchIndexActivityArguments from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentSearchIndexActivityArguments if the JsonReader was pointing to an instance + * of it, or null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the KnowledgeAgentSearchIndexActivityArguments. + */ + @Generated + public static KnowledgeAgentSearchIndexActivityArguments fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + KnowledgeAgentSearchIndexActivityArguments deserializedKnowledgeAgentSearchIndexActivityArguments + = new KnowledgeAgentSearchIndexActivityArguments(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("search".equals(fieldName)) { + deserializedKnowledgeAgentSearchIndexActivityArguments.search = reader.getString(); + } else if ("filter".equals(fieldName)) { + deserializedKnowledgeAgentSearchIndexActivityArguments.filter = reader.getString(); + } else { + reader.skipChildren(); + } + } + + return deserializedKnowledgeAgentSearchIndexActivityArguments; + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityRecord.java new file mode 100644 index 000000000000..aa773de4b0a1 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexActivityRecord.java @@ -0,0 +1,197 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.CoreUtils; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Represents a search index retrieval activity record. + */ +@Fluent +public final class KnowledgeAgentSearchIndexActivityRecord extends KnowledgeAgentRetrievalActivityRecord { + /* + * The type of the activity record. + */ + @Generated + private String type = "searchIndex"; + + /* + * The search index arguments for the retrieval activity. + */ + @Generated + private KnowledgeAgentSearchIndexActivityArguments searchIndexArguments; + + /** + * Creates an instance of KnowledgeAgentSearchIndexActivityRecord class. + * + * @param id the id value to set. + */ + @Generated + public KnowledgeAgentSearchIndexActivityRecord(int id) { + super(id); + } + + /** + * Get the type property: The type of the activity record. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the searchIndexArguments property: The search index arguments for the retrieval activity. + * + * @return the searchIndexArguments value. + */ + @Generated + public KnowledgeAgentSearchIndexActivityArguments getSearchIndexArguments() { + return this.searchIndexArguments; + } + + /** + * Set the searchIndexArguments property: The search index arguments for the retrieval activity. + * + * @param searchIndexArguments the searchIndexArguments value to set. + * @return the KnowledgeAgentSearchIndexActivityRecord object itself. + */ + @Generated + public KnowledgeAgentSearchIndexActivityRecord + setSearchIndexArguments(KnowledgeAgentSearchIndexActivityArguments searchIndexArguments) { + this.searchIndexArguments = searchIndexArguments; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentSearchIndexActivityRecord setKnowledgeSourceName(String knowledgeSourceName) { + super.setKnowledgeSourceName(knowledgeSourceName); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentSearchIndexActivityRecord setQueryTime(OffsetDateTime queryTime) { + super.setQueryTime(queryTime); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentSearchIndexActivityRecord setCount(Integer count) { + super.setCount(count); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentSearchIndexActivityRecord setElapsedMs(Integer elapsedMs) { + super.setElapsedMs(elapsedMs); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeIntField("id", getId()); + jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); + jsonWriter.writeStringField("knowledgeSourceName", getKnowledgeSourceName()); + jsonWriter.writeStringField("queryTime", + getQueryTime() == null ? null : DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(getQueryTime())); + jsonWriter.writeNumberField("count", getCount()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeJsonField("searchIndexArguments", this.searchIndexArguments); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentSearchIndexActivityRecord from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentSearchIndexActivityRecord if the JsonReader was pointing to an instance of + * it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentSearchIndexActivityRecord. + */ + @Generated + public static KnowledgeAgentSearchIndexActivityRecord fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + int id = 0; + Integer elapsedMs = null; + String knowledgeSourceName = null; + OffsetDateTime queryTime = null; + Integer count = null; + String type = "searchIndex"; + KnowledgeAgentSearchIndexActivityArguments searchIndexArguments = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getInt(); + idFound = true; + } else if ("elapsedMs".equals(fieldName)) { + elapsedMs = reader.getNullable(JsonReader::getInt); + } else if ("knowledgeSourceName".equals(fieldName)) { + knowledgeSourceName = reader.getString(); + } else if ("queryTime".equals(fieldName)) { + queryTime = reader + .getNullable(nonNullReader -> CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); + } else if ("count".equals(fieldName)) { + count = reader.getNullable(JsonReader::getInt); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("searchIndexArguments".equals(fieldName)) { + searchIndexArguments = KnowledgeAgentSearchIndexActivityArguments.fromJson(reader); + } else { + reader.skipChildren(); + } + } + if (idFound) { + KnowledgeAgentSearchIndexActivityRecord deserializedKnowledgeAgentSearchIndexActivityRecord + = new KnowledgeAgentSearchIndexActivityRecord(id); + deserializedKnowledgeAgentSearchIndexActivityRecord.setElapsedMs(elapsedMs); + deserializedKnowledgeAgentSearchIndexActivityRecord.setKnowledgeSourceName(knowledgeSourceName); + deserializedKnowledgeAgentSearchIndexActivityRecord.setQueryTime(queryTime); + deserializedKnowledgeAgentSearchIndexActivityRecord.setCount(count); + deserializedKnowledgeAgentSearchIndexActivityRecord.type = type; + deserializedKnowledgeAgentSearchIndexActivityRecord.searchIndexArguments = searchIndexArguments; + + return deserializedKnowledgeAgentSearchIndexActivityRecord; + } + throw new IllegalStateException("Missing required property: id"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexReference.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexReference.java new file mode 100644 index 000000000000..86d9f7d7e810 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSearchIndexReference.java @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Represents an Azure Search document reference. + */ +@Fluent +public final class KnowledgeAgentSearchIndexReference extends KnowledgeAgentReference { + /* + * The type of the reference. + */ + @Generated + private String type = "searchIndex"; + + /* + * The document key for the reference. + */ + @Generated + private String docKey; + + /** + * Creates an instance of KnowledgeAgentSearchIndexReference class. + * + * @param id the id value to set. + * @param activitySource the activitySource value to set. + */ + @Generated + public KnowledgeAgentSearchIndexReference(String id, int activitySource) { + super(id, activitySource); + } + + /** + * Get the type property: The type of the reference. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the docKey property: The document key for the reference. + * + * @return the docKey value. + */ + @Generated + public String getDocKey() { + return this.docKey; + } + + /** + * Set the docKey property: The document key for the reference. + * + * @param docKey the docKey value to set. + * @return the KnowledgeAgentSearchIndexReference object itself. + */ + @Generated + public KnowledgeAgentSearchIndexReference setDocKey(String docKey) { + this.docKey = docKey; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentSearchIndexReference setSourceData(Map sourceData) { + super.setSourceData(sourceData); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentSearchIndexReference setRerankerScore(Float rerankerScore) { + super.setRerankerScore(rerankerScore); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", getId()); + jsonWriter.writeIntField("activitySource", getActivitySource()); + jsonWriter.writeMapField("sourceData", getSourceData(), (writer, element) -> writer.writeUntyped(element)); + jsonWriter.writeNumberField("rerankerScore", getRerankerScore()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("docKey", this.docKey); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentSearchIndexReference from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentSearchIndexReference if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentSearchIndexReference. + */ + @Generated + public static KnowledgeAgentSearchIndexReference fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + String id = null; + boolean activitySourceFound = false; + int activitySource = 0; + Map sourceData = null; + Float rerankerScore = null; + String type = "searchIndex"; + String docKey = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getString(); + idFound = true; + } else if ("activitySource".equals(fieldName)) { + activitySource = reader.getInt(); + activitySourceFound = true; + } else if ("sourceData".equals(fieldName)) { + sourceData = reader.readMap(reader1 -> reader1.readUntyped()); + } else if ("rerankerScore".equals(fieldName)) { + rerankerScore = reader.getNullable(JsonReader::getFloat); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("docKey".equals(fieldName)) { + docKey = reader.getString(); + } else { + reader.skipChildren(); + } + } + if (idFound && activitySourceFound) { + KnowledgeAgentSearchIndexReference deserializedKnowledgeAgentSearchIndexReference + = new KnowledgeAgentSearchIndexReference(id, activitySource); + deserializedKnowledgeAgentSearchIndexReference.setSourceData(sourceData); + deserializedKnowledgeAgentSearchIndexReference.setRerankerScore(rerankerScore); + deserializedKnowledgeAgentSearchIndexReference.type = type; + deserializedKnowledgeAgentSearchIndexReference.docKey = docKey; + + return deserializedKnowledgeAgentSearchIndexReference; + } + List missingProperties = new ArrayList<>(); + if (!idFound) { + missingProperties.add("id"); + } + if (!activitySourceFound) { + missingProperties.add("activitySource"); + } + + throw new IllegalStateException( + "Missing required property/properties: " + String.join(", ", missingProperties)); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSemanticRerankerActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSemanticRerankerActivityRecord.java new file mode 100644 index 000000000000..c2a7d4b96004 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentSemanticRerankerActivityRecord.java @@ -0,0 +1,146 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Represents a semantic ranker activity record. + */ +@Fluent +public final class KnowledgeAgentSemanticRerankerActivityRecord extends KnowledgeAgentActivityRecord { + /* + * The type of the activity record. + */ + @Generated + private String type = "semanticReranker"; + + /* + * The number of input tokens for the semantic ranker activity. + */ + @Generated + private Integer inputTokens; + + /** + * Creates an instance of KnowledgeAgentSemanticRerankerActivityRecord class. + * + * @param id the id value to set. + */ + @Generated + public KnowledgeAgentSemanticRerankerActivityRecord(int id) { + super(id); + } + + /** + * Get the type property: The type of the activity record. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the inputTokens property: The number of input tokens for the semantic ranker activity. + * + * @return the inputTokens value. + */ + @Generated + public Integer getInputTokens() { + return this.inputTokens; + } + + /** + * Set the inputTokens property: The number of input tokens for the semantic ranker activity. + * + * @param inputTokens the inputTokens value to set. + * @return the KnowledgeAgentSemanticRerankerActivityRecord object itself. + */ + @Generated + public KnowledgeAgentSemanticRerankerActivityRecord setInputTokens(Integer inputTokens) { + this.inputTokens = inputTokens; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentSemanticRerankerActivityRecord setElapsedMs(Integer elapsedMs) { + super.setElapsedMs(elapsedMs); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeIntField("id", getId()); + jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeNumberField("inputTokens", this.inputTokens); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentSemanticRerankerActivityRecord from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentSemanticRerankerActivityRecord if the JsonReader was pointing to an instance + * of it, or null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentSemanticRerankerActivityRecord. + */ + @Generated + public static KnowledgeAgentSemanticRerankerActivityRecord fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + int id = 0; + Integer elapsedMs = null; + String type = "semanticReranker"; + Integer inputTokens = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getInt(); + idFound = true; + } else if ("elapsedMs".equals(fieldName)) { + elapsedMs = reader.getNullable(JsonReader::getInt); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("inputTokens".equals(fieldName)) { + inputTokens = reader.getNullable(JsonReader::getInt); + } else { + reader.skipChildren(); + } + } + if (idFound) { + KnowledgeAgentSemanticRerankerActivityRecord deserializedKnowledgeAgentSemanticRerankerActivityRecord + = new KnowledgeAgentSemanticRerankerActivityRecord(id); + deserializedKnowledgeAgentSemanticRerankerActivityRecord.setElapsedMs(elapsedMs); + deserializedKnowledgeAgentSemanticRerankerActivityRecord.type = type; + deserializedKnowledgeAgentSemanticRerankerActivityRecord.inputTokens = inputTokens; + + return deserializedKnowledgeAgentSemanticRerankerActivityRecord; + } + throw new IllegalStateException("Missing required property: id"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java new file mode 100644 index 000000000000..9cf9ec98bb45 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Represents the arguments the web retrieval activity was run with. + */ +@Fluent +public final class KnowledgeAgentWebActivityArguments implements JsonSerializable { + /* + * The search string used to query the web. + */ + @Generated + private String search; + + /* + * The freshness for the retrieval activity. + */ + @Generated + private String freshness; + + /** + * Creates an instance of KnowledgeAgentWebActivityArguments class. + */ + @Generated + public KnowledgeAgentWebActivityArguments() { + } + + /** + * Get the search property: The search string used to query the web. + * + * @return the search value. + */ + @Generated + public String getSearch() { + return this.search; + } + + /** + * Set the search property: The search string used to query the web. + * + * @param search the search value to set. + * @return the KnowledgeAgentWebActivityArguments object itself. + */ + @Generated + public KnowledgeAgentWebActivityArguments setSearch(String search) { + this.search = search; + return this; + } + + /** + * Get the freshness property: The freshness for the retrieval activity. + * + * @return the freshness value. + */ + @Generated + public String getFreshness() { + return this.freshness; + } + + /** + * Set the freshness property: The freshness for the retrieval activity. + * + * @param freshness the freshness value to set. + * @return the KnowledgeAgentWebActivityArguments object itself. + */ + @Generated + public KnowledgeAgentWebActivityArguments setFreshness(String freshness) { + this.freshness = freshness; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("search", this.search); + jsonWriter.writeStringField("freshness", this.freshness); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentWebActivityArguments from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentWebActivityArguments if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the KnowledgeAgentWebActivityArguments. + */ + @Generated + public static KnowledgeAgentWebActivityArguments fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + KnowledgeAgentWebActivityArguments deserializedKnowledgeAgentWebActivityArguments + = new KnowledgeAgentWebActivityArguments(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("search".equals(fieldName)) { + deserializedKnowledgeAgentWebActivityArguments.search = reader.getString(); + } else if ("freshness".equals(fieldName)) { + deserializedKnowledgeAgentWebActivityArguments.freshness = reader.getString(); + } else { + reader.skipChildren(); + } + } + + return deserializedKnowledgeAgentWebActivityArguments; + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java new file mode 100644 index 000000000000..9bfb61f3dc73 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java @@ -0,0 +1,196 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.core.util.CoreUtils; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Represents a web retrieval activity record. + */ +@Fluent +public final class KnowledgeAgentWebActivityRecord extends KnowledgeAgentRetrievalActivityRecord { + /* + * The type of the activity record. + */ + @Generated + private String type = "web"; + + /* + * The web arguments for the retrieval activity. + */ + @Generated + private KnowledgeAgentWebActivityArguments webArguments; + + /** + * Creates an instance of KnowledgeAgentWebActivityRecord class. + * + * @param id the id value to set. + */ + @Generated + public KnowledgeAgentWebActivityRecord(int id) { + super(id); + } + + /** + * Get the type property: The type of the activity record. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the webArguments property: The web arguments for the retrieval activity. + * + * @return the webArguments value. + */ + @Generated + public KnowledgeAgentWebActivityArguments getWebArguments() { + return this.webArguments; + } + + /** + * Set the webArguments property: The web arguments for the retrieval activity. + * + * @param webArguments the webArguments value to set. + * @return the KnowledgeAgentWebActivityRecord object itself. + */ + @Generated + public KnowledgeAgentWebActivityRecord setWebArguments(KnowledgeAgentWebActivityArguments webArguments) { + this.webArguments = webArguments; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentWebActivityRecord setKnowledgeSourceName(String knowledgeSourceName) { + super.setKnowledgeSourceName(knowledgeSourceName); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentWebActivityRecord setQueryTime(OffsetDateTime queryTime) { + super.setQueryTime(queryTime); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentWebActivityRecord setCount(Integer count) { + super.setCount(count); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentWebActivityRecord setElapsedMs(Integer elapsedMs) { + super.setElapsedMs(elapsedMs); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeIntField("id", getId()); + jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); + jsonWriter.writeStringField("knowledgeSourceName", getKnowledgeSourceName()); + jsonWriter.writeStringField("queryTime", + getQueryTime() == null ? null : DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(getQueryTime())); + jsonWriter.writeNumberField("count", getCount()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeJsonField("webArguments", this.webArguments); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentWebActivityRecord from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentWebActivityRecord if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentWebActivityRecord. + */ + @Generated + public static KnowledgeAgentWebActivityRecord fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + int id = 0; + Integer elapsedMs = null; + String knowledgeSourceName = null; + OffsetDateTime queryTime = null; + Integer count = null; + String type = "web"; + KnowledgeAgentWebActivityArguments webArguments = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getInt(); + idFound = true; + } else if ("elapsedMs".equals(fieldName)) { + elapsedMs = reader.getNullable(JsonReader::getInt); + } else if ("knowledgeSourceName".equals(fieldName)) { + knowledgeSourceName = reader.getString(); + } else if ("queryTime".equals(fieldName)) { + queryTime = reader + .getNullable(nonNullReader -> CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); + } else if ("count".equals(fieldName)) { + count = reader.getNullable(JsonReader::getInt); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("webArguments".equals(fieldName)) { + webArguments = KnowledgeAgentWebActivityArguments.fromJson(reader); + } else { + reader.skipChildren(); + } + } + if (idFound) { + KnowledgeAgentWebActivityRecord deserializedKnowledgeAgentWebActivityRecord + = new KnowledgeAgentWebActivityRecord(id); + deserializedKnowledgeAgentWebActivityRecord.setElapsedMs(elapsedMs); + deserializedKnowledgeAgentWebActivityRecord.setKnowledgeSourceName(knowledgeSourceName); + deserializedKnowledgeAgentWebActivityRecord.setQueryTime(queryTime); + deserializedKnowledgeAgentWebActivityRecord.setCount(count); + deserializedKnowledgeAgentWebActivityRecord.type = type; + deserializedKnowledgeAgentWebActivityRecord.webArguments = webArguments; + + return deserializedKnowledgeAgentWebActivityRecord; + } + throw new IllegalStateException("Missing required property: id"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java new file mode 100644 index 000000000000..703d60ae7339 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Represents a web document reference. + */ +@Fluent +public final class KnowledgeAgentWebReference extends KnowledgeAgentReference { + /* + * The type of the reference. + */ + @Generated + private String type = "web"; + + /* + * The url the reference data originated from. + */ + @Generated + private String url; + + /** + * Creates an instance of KnowledgeAgentWebReference class. + * + * @param id the id value to set. + * @param activitySource the activitySource value to set. + */ + @Generated + public KnowledgeAgentWebReference(String id, int activitySource) { + super(id, activitySource); + } + + /** + * Get the type property: The type of the reference. + * + * @return the type value. + */ + @Generated + @Override + public String getType() { + return this.type; + } + + /** + * Get the url property: The url the reference data originated from. + * + * @return the url value. + */ + @Generated + public String getUrl() { + return this.url; + } + + /** + * Set the url property: The url the reference data originated from. + * + * @param url the url value to set. + * @return the KnowledgeAgentWebReference object itself. + */ + @Generated + public KnowledgeAgentWebReference setUrl(String url) { + this.url = url; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentWebReference setSourceData(Map sourceData) { + super.setSourceData(sourceData); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public KnowledgeAgentWebReference setRerankerScore(Float rerankerScore) { + super.setRerankerScore(rerankerScore); + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("id", getId()); + jsonWriter.writeIntField("activitySource", getActivitySource()); + jsonWriter.writeMapField("sourceData", getSourceData(), (writer, element) -> writer.writeUntyped(element)); + jsonWriter.writeNumberField("rerankerScore", getRerankerScore()); + jsonWriter.writeStringField("type", this.type); + jsonWriter.writeStringField("url", this.url); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeAgentWebReference from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeAgentWebReference if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeAgentWebReference. + */ + @Generated + public static KnowledgeAgentWebReference fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean idFound = false; + String id = null; + boolean activitySourceFound = false; + int activitySource = 0; + Map sourceData = null; + Float rerankerScore = null; + String type = "web"; + String url = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("id".equals(fieldName)) { + id = reader.getString(); + idFound = true; + } else if ("activitySource".equals(fieldName)) { + activitySource = reader.getInt(); + activitySourceFound = true; + } else if ("sourceData".equals(fieldName)) { + sourceData = reader.readMap(reader1 -> reader1.readUntyped()); + } else if ("rerankerScore".equals(fieldName)) { + rerankerScore = reader.getNullable(JsonReader::getFloat); + } else if ("type".equals(fieldName)) { + type = reader.getString(); + } else if ("url".equals(fieldName)) { + url = reader.getString(); + } else { + reader.skipChildren(); + } + } + if (idFound && activitySourceFound) { + KnowledgeAgentWebReference deserializedKnowledgeAgentWebReference + = new KnowledgeAgentWebReference(id, activitySource); + deserializedKnowledgeAgentWebReference.setSourceData(sourceData); + deserializedKnowledgeAgentWebReference.setRerankerScore(rerankerScore); + deserializedKnowledgeAgentWebReference.type = type; + deserializedKnowledgeAgentWebReference.url = url; + + return deserializedKnowledgeAgentWebReference; + } + List missingProperties = new ArrayList<>(); + if (!idFound) { + missingProperties.add("id"); + } + if (!activitySourceFound) { + missingProperties.add("activitySource"); + } + + throw new IllegalStateException( + "Missing required property/properties: " + String.join(", ", missingProperties)); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java new file mode 100644 index 000000000000..f7a2c52136f7 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The kind of the knowledge source. + */ +public final class KnowledgeSourceKind extends ExpandableStringEnum { + /** + * A knowledge source that reads data from a Search Index. + */ + @Generated + public static final KnowledgeSourceKind SEARCH_INDEX = fromString("searchIndex"); + + /** + * A knowledge source that read and ingest data from Azure Blob Storage to a Search Index. + */ + @Generated + public static final KnowledgeSourceKind AZURE_BLOB = fromString("azureBlob"); + + /** + * A knowledge source that reads data from the web. + */ + @Generated + public static final KnowledgeSourceKind WEB = fromString("web"); + + /** + * Creates a new instance of KnowledgeSourceKind value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public KnowledgeSourceKind() { + } + + /** + * Creates or finds a KnowledgeSourceKind from its string representation. + * + * @param name a name to look for. + * @return the corresponding KnowledgeSourceKind. + */ + @Generated + public static KnowledgeSourceKind fromString(String name) { + return fromString(name, KnowledgeSourceKind.class); + } + + /** + * Gets known KnowledgeSourceKind values. + * + * @return known KnowledgeSourceKind values. + */ + @Generated + public static Collection values() { + return values(KnowledgeSourceKind.class); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceParams.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceParams.java new file mode 100644 index 000000000000..9ca809fab51e --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceParams.java @@ -0,0 +1,142 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * The KnowledgeSourceParams model. + */ +@Immutable +public class KnowledgeSourceParams implements JsonSerializable { + /* + * The type of the knowledge source. + */ + @Generated + private KnowledgeSourceKind kind = KnowledgeSourceKind.fromString("KnowledgeSourceParams"); + + /* + * The name of the index the params apply to. + */ + @Generated + private final String knowledgeSourceName; + + /** + * Creates an instance of KnowledgeSourceParams class. + * + * @param knowledgeSourceName the knowledgeSourceName value to set. + */ + @Generated + public KnowledgeSourceParams(String knowledgeSourceName) { + this.knowledgeSourceName = knowledgeSourceName; + } + + /** + * Get the kind property: The type of the knowledge source. + * + * @return the kind value. + */ + @Generated + public KnowledgeSourceKind getKind() { + return this.kind; + } + + /** + * Get the knowledgeSourceName property: The name of the index the params apply to. + * + * @return the knowledgeSourceName value. + */ + @Generated + public String getKnowledgeSourceName() { + return this.knowledgeSourceName; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("knowledgeSourceName", this.knowledgeSourceName); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of KnowledgeSourceParams from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of KnowledgeSourceParams if the JsonReader was pointing to an instance of it, or null if it + * was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the KnowledgeSourceParams. + */ + @Generated + public static KnowledgeSourceParams fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + String discriminatorValue = null; + try (JsonReader readerToUse = reader.bufferObject()) { + readerToUse.nextToken(); // Prepare for reading + while (readerToUse.nextToken() != JsonToken.END_OBJECT) { + String fieldName = readerToUse.getFieldName(); + readerToUse.nextToken(); + if ("kind".equals(fieldName)) { + discriminatorValue = readerToUse.getString(); + break; + } else { + readerToUse.skipChildren(); + } + } + // Use the discriminator value to determine which subtype should be deserialized. + if ("searchIndex".equals(discriminatorValue)) { + return SearchIndexKnowledgeSourceParams.fromJson(readerToUse.reset()); + } else if ("web".equals(discriminatorValue)) { + return WebKnowledgeSourceParams.fromJson(readerToUse.reset()); + } else { + return fromJsonKnownDiscriminator(readerToUse.reset()); + } + } + }); + } + + @Generated + static KnowledgeSourceParams fromJsonKnownDiscriminator(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean knowledgeSourceNameFound = false; + String knowledgeSourceName = null; + KnowledgeSourceKind kind = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("knowledgeSourceName".equals(fieldName)) { + knowledgeSourceName = reader.getString(); + knowledgeSourceNameFound = true; + } else if ("kind".equals(fieldName)) { + kind = KnowledgeSourceKind.fromString(reader.getString()); + } else { + reader.skipChildren(); + } + } + if (knowledgeSourceNameFound) { + KnowledgeSourceParams deserializedKnowledgeSourceParams + = new KnowledgeSourceParams(knowledgeSourceName); + deserializedKnowledgeSourceParams.kind = kind; + + return deserializedKnowledgeSourceParams; + } + throw new IllegalStateException("Missing required property: knowledgeSourceName"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/SearchIndexKnowledgeSourceParams.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/SearchIndexKnowledgeSourceParams.java new file mode 100644 index 000000000000..fe42fc3cb002 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/SearchIndexKnowledgeSourceParams.java @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Specifies runtime parameters for a search index knowledge source. + */ +@Fluent +public final class SearchIndexKnowledgeSourceParams extends KnowledgeSourceParams { + /* + * The type of the knowledge source. + */ + @Generated + private KnowledgeSourceKind kind = KnowledgeSourceKind.SEARCH_INDEX; + + /* + * A filter condition applied to the index (e.g., 'State eq VA'). + */ + @Generated + private String filterAddOn; + + /** + * Creates an instance of SearchIndexKnowledgeSourceParams class. + * + * @param knowledgeSourceName the knowledgeSourceName value to set. + */ + @Generated + public SearchIndexKnowledgeSourceParams(String knowledgeSourceName) { + super(knowledgeSourceName); + } + + /** + * Get the kind property: The type of the knowledge source. + * + * @return the kind value. + */ + @Generated + @Override + public KnowledgeSourceKind getKind() { + return this.kind; + } + + /** + * Get the filterAddOn property: A filter condition applied to the index (e.g., 'State eq VA'). + * + * @return the filterAddOn value. + */ + @Generated + public String getFilterAddOn() { + return this.filterAddOn; + } + + /** + * Set the filterAddOn property: A filter condition applied to the index (e.g., 'State eq VA'). + * + * @param filterAddOn the filterAddOn value to set. + * @return the SearchIndexKnowledgeSourceParams object itself. + */ + @Generated + public SearchIndexKnowledgeSourceParams setFilterAddOn(String filterAddOn) { + this.filterAddOn = filterAddOn; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("knowledgeSourceName", getKnowledgeSourceName()); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeStringField("filterAddOn", this.filterAddOn); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of SearchIndexKnowledgeSourceParams from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of SearchIndexKnowledgeSourceParams if the JsonReader was pointing to an instance of it, or + * null if it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the SearchIndexKnowledgeSourceParams. + */ + @Generated + public static SearchIndexKnowledgeSourceParams fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean knowledgeSourceNameFound = false; + String knowledgeSourceName = null; + KnowledgeSourceKind kind = KnowledgeSourceKind.SEARCH_INDEX; + String filterAddOn = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("knowledgeSourceName".equals(fieldName)) { + knowledgeSourceName = reader.getString(); + knowledgeSourceNameFound = true; + } else if ("kind".equals(fieldName)) { + kind = KnowledgeSourceKind.fromString(reader.getString()); + } else if ("filterAddOn".equals(fieldName)) { + filterAddOn = reader.getString(); + } else { + reader.skipChildren(); + } + } + if (knowledgeSourceNameFound) { + SearchIndexKnowledgeSourceParams deserializedSearchIndexKnowledgeSourceParams + = new SearchIndexKnowledgeSourceParams(knowledgeSourceName); + deserializedSearchIndexKnowledgeSourceParams.kind = kind; + deserializedSearchIndexKnowledgeSourceParams.filterAddOn = filterAddOn; + + return deserializedSearchIndexKnowledgeSourceParams; + } + throw new IllegalStateException("Missing required property: knowledgeSourceName"); + }); + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java new file mode 100644 index 000000000000..b1b6dd42b7b1 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +package com.azure.search.documents.agents.models; + +import com.azure.core.annotation.Fluent; +import com.azure.core.annotation.Generated; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * Specifies runtime parameters for a web knowledge source. + */ +@Fluent +public final class WebKnowledgeSourceParams extends KnowledgeSourceParams { + /* + * The type of the knowledge source. + */ + @Generated + private KnowledgeSourceKind kind = KnowledgeSourceKind.WEB; + + /* + * The freshness of web results. + */ + @Generated + private String freshness; + + /** + * Creates an instance of WebKnowledgeSourceParams class. + * + * @param knowledgeSourceName the knowledgeSourceName value to set. + */ + @Generated + public WebKnowledgeSourceParams(String knowledgeSourceName) { + super(knowledgeSourceName); + } + + /** + * Get the kind property: The type of the knowledge source. + * + * @return the kind value. + */ + @Generated + @Override + public KnowledgeSourceKind getKind() { + return this.kind; + } + + /** + * Get the freshness property: The freshness of web results. + * + * @return the freshness value. + */ + @Generated + public String getFreshness() { + return this.freshness; + } + + /** + * Set the freshness property: The freshness of web results. + * + * @param freshness the freshness value to set. + * @return the WebKnowledgeSourceParams object itself. + */ + @Generated + public WebKnowledgeSourceParams setFreshness(String freshness) { + this.freshness = freshness; + return this; + } + + /** + * {@inheritDoc} + */ + @Generated + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + jsonWriter.writeStringField("knowledgeSourceName", getKnowledgeSourceName()); + jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); + jsonWriter.writeStringField("freshness", this.freshness); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of WebKnowledgeSourceParams from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of WebKnowledgeSourceParams if the JsonReader was pointing to an instance of it, or null if + * it was pointing to JSON null. + * @throws IllegalStateException If the deserialized JSON object was missing any required properties. + * @throws IOException If an error occurs while reading the WebKnowledgeSourceParams. + */ + @Generated + public static WebKnowledgeSourceParams fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + boolean knowledgeSourceNameFound = false; + String knowledgeSourceName = null; + KnowledgeSourceKind kind = KnowledgeSourceKind.WEB; + String freshness = null; + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("knowledgeSourceName".equals(fieldName)) { + knowledgeSourceName = reader.getString(); + knowledgeSourceNameFound = true; + } else if ("kind".equals(fieldName)) { + kind = KnowledgeSourceKind.fromString(reader.getString()); + } else if ("freshness".equals(fieldName)) { + freshness = reader.getString(); + } else { + reader.skipChildren(); + } + } + if (knowledgeSourceNameFound) { + WebKnowledgeSourceParams deserializedWebKnowledgeSourceParams + = new WebKnowledgeSourceParams(knowledgeSourceName); + deserializedWebKnowledgeSourceParams.kind = kind; + deserializedWebKnowledgeSourceParams.freshness = freshness; + + return deserializedWebKnowledgeSourceParams; + } + throw new IllegalStateException("Missing required property: knowledgeSourceName"); + }); + } +} From a1479ee0dce04de634abf917ac44f7f8862a195f Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:26:14 -0400 Subject: [PATCH 04/12] Make SearchIndexerStatus.name optional for backwards compatibility --- .../indexes/models/SearchIndexerStatus.java | 24 +++++++------------ .../azure-search-documents/swagger/README.md | 9 +++++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java index cdf07db54784..a6fa043b0229 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/SearchIndexerStatus.java @@ -25,7 +25,7 @@ public final class SearchIndexerStatus implements JsonSerializable executionHistory, + public SearchIndexerStatus(IndexerStatus status, List executionHistory, SearchIndexerLimits limits) { - this.name = name; this.status = status; this.executionHistory = executionHistory; this.limits = limits; @@ -157,24 +155,20 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { @Generated public static SearchIndexerStatus fromJson(JsonReader jsonReader) throws IOException { return jsonReader.readObject(reader -> { - boolean nameFound = false; - String name = null; boolean statusFound = false; IndexerStatus status = null; boolean executionHistoryFound = false; List executionHistory = null; boolean limitsFound = false; SearchIndexerLimits limits = null; + String name = null; IndexerExecutionResult lastResult = null; IndexerCurrentState currentState = null; while (reader.nextToken() != JsonToken.END_OBJECT) { String fieldName = reader.getFieldName(); reader.nextToken(); - if ("name".equals(fieldName)) { - name = reader.getString(); - nameFound = true; - } else if ("status".equals(fieldName)) { + if ("status".equals(fieldName)) { status = IndexerStatus.fromString(reader.getString()); statusFound = true; } else if ("executionHistory".equals(fieldName)) { @@ -183,6 +177,8 @@ public static SearchIndexerStatus fromJson(JsonReader jsonReader) throws IOExcep } else if ("limits".equals(fieldName)) { limits = SearchIndexerLimits.fromJson(reader); limitsFound = true; + } else if ("name".equals(fieldName)) { + name = reader.getString(); } else if ("lastResult".equals(fieldName)) { lastResult = IndexerExecutionResult.fromJson(reader); } else if ("currentState".equals(fieldName)) { @@ -191,18 +187,16 @@ public static SearchIndexerStatus fromJson(JsonReader jsonReader) throws IOExcep reader.skipChildren(); } } - if (nameFound && statusFound && executionHistoryFound && limitsFound) { + if (statusFound && executionHistoryFound && limitsFound) { SearchIndexerStatus deserializedSearchIndexerStatus - = new SearchIndexerStatus(name, status, executionHistory, limits); + = new SearchIndexerStatus(status, executionHistory, limits); + deserializedSearchIndexerStatus.name = name; deserializedSearchIndexerStatus.lastResult = lastResult; deserializedSearchIndexerStatus.currentState = currentState; return deserializedSearchIndexerStatus; } List missingProperties = new ArrayList<>(); - if (!nameFound) { - missingProperties.add("name"); - } if (!statusFound) { missingProperties.add("status"); } diff --git a/sdk/search/azure-search-documents/swagger/README.md b/sdk/search/azure-search-documents/swagger/README.md index 817b0a7f6d23..ffd748333602 100644 --- a/sdk/search/azure-search-documents/swagger/README.md +++ b/sdk/search/azure-search-documents/swagger/README.md @@ -478,3 +478,12 @@ directive: $.find(p => p.name === "speller")["x-ms-enum"].name = "QuerySpellerType"; ``` +### Make `SearchIndexerStatus.name` optional + +```yaml $(tag) == 'searchservice' +directive: +- from: swagger-document + where: $.definitions.SearchIndexerStatus + transform: > + $.required = $.required.filter((required) => required !== "name"); +``` From 815886712d641ad88436dddc4d197b7c5499485f Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Fri, 8 Aug 2025 09:57:18 -0400 Subject: [PATCH 05/12] Small API cleanup --- .../implementation/KnowledgeAgentsImpl.java | 2 +- .../implementation/KnowledgeSourcesImpl.java | 2 +- .../SearchServiceClientImpl.java | 2 +- .../models/ListIndexStatsSummary.java | 3 +- .../models/ListKnowledgeAgentsResult.java | 3 +- .../models/ListKnowledgeSourcesResult.java | 3 +- .../KnowledgeAgentOutputOptimization.java | 53 ------------------- .../azure-search-documents/swagger/README.md | 11 +++- 8 files changed, 19 insertions(+), 60 deletions(-) rename sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/{ => implementation}/models/ListIndexStatsSummary.java (95%) rename sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/{ => implementation}/models/ListKnowledgeAgentsResult.java (96%) rename sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/{ => implementation}/models/ListKnowledgeSourcesResult.java (96%) delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeAgentsImpl.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeAgentsImpl.java index 1837f59e33fc..b0ed51f9845d 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeAgentsImpl.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeAgentsImpl.java @@ -30,9 +30,9 @@ import com.azure.core.util.Context; import com.azure.core.util.FluxUtil; import com.azure.search.documents.indexes.implementation.models.ErrorResponseException; +import com.azure.search.documents.indexes.implementation.models.ListKnowledgeAgentsResult; import com.azure.search.documents.indexes.implementation.models.RequestOptions; import com.azure.search.documents.indexes.models.KnowledgeAgent; -import com.azure.search.documents.indexes.models.ListKnowledgeAgentsResult; import java.util.UUID; import reactor.core.publisher.Mono; diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java index e48ce3545d81..b95602eac06c 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/KnowledgeSourcesImpl.java @@ -30,9 +30,9 @@ import com.azure.core.util.Context; import com.azure.core.util.FluxUtil; import com.azure.search.documents.indexes.implementation.models.ErrorResponseException; +import com.azure.search.documents.indexes.implementation.models.ListKnowledgeSourcesResult; import com.azure.search.documents.indexes.implementation.models.RequestOptions; import com.azure.search.documents.indexes.models.KnowledgeSource; -import com.azure.search.documents.indexes.models.ListKnowledgeSourcesResult; import java.util.UUID; import reactor.core.publisher.Mono; diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java index b76f2121161e..ba60d0a1a940 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/SearchServiceClientImpl.java @@ -31,9 +31,9 @@ import com.azure.core.util.serializer.JacksonAdapter; import com.azure.core.util.serializer.SerializerAdapter; import com.azure.search.documents.indexes.implementation.models.ErrorResponseException; +import com.azure.search.documents.indexes.implementation.models.ListIndexStatsSummary; import com.azure.search.documents.indexes.implementation.models.RequestOptions; import com.azure.search.documents.indexes.models.IndexStatisticsSummary; -import com.azure.search.documents.indexes.models.ListIndexStatsSummary; import com.azure.search.documents.indexes.models.SearchServiceStatistics; import java.util.UUID; import reactor.core.publisher.Mono; diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListIndexStatsSummary.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListIndexStatsSummary.java similarity index 95% rename from sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListIndexStatsSummary.java rename to sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListIndexStatsSummary.java index 1f692517cd20..51c1697ea380 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListIndexStatsSummary.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListIndexStatsSummary.java @@ -4,7 +4,7 @@ // Code generated by Microsoft (R) AutoRest Code Generator. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -package com.azure.search.documents.indexes.models; +package com.azure.search.documents.indexes.implementation.models; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; @@ -12,6 +12,7 @@ import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.azure.search.documents.indexes.models.IndexStatisticsSummary; import java.io.IOException; import java.util.List; diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeAgentsResult.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListKnowledgeAgentsResult.java similarity index 96% rename from sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeAgentsResult.java rename to sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListKnowledgeAgentsResult.java index 6657c3f6229c..e0f48788c16a 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeAgentsResult.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListKnowledgeAgentsResult.java @@ -4,7 +4,7 @@ // Code generated by Microsoft (R) AutoRest Code Generator. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -package com.azure.search.documents.indexes.models; +package com.azure.search.documents.indexes.implementation.models; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; @@ -12,6 +12,7 @@ import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.azure.search.documents.indexes.models.KnowledgeAgent; import java.io.IOException; import java.util.List; diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeSourcesResult.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListKnowledgeSourcesResult.java similarity index 96% rename from sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeSourcesResult.java rename to sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListKnowledgeSourcesResult.java index 6c313dda8a48..83a17d1cf434 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/ListKnowledgeSourcesResult.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/implementation/models/ListKnowledgeSourcesResult.java @@ -4,7 +4,7 @@ // Code generated by Microsoft (R) AutoRest Code Generator. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -package com.azure.search.documents.indexes.models; +package com.azure.search.documents.indexes.implementation.models; import com.azure.core.annotation.Generated; import com.azure.core.annotation.Immutable; @@ -12,6 +12,7 @@ import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; import com.azure.json.JsonWriter; +import com.azure.search.documents.indexes.models.KnowledgeSource; import java.io.IOException; import java.util.List; diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java deleted file mode 100644 index 63e968afa46a..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeAgentOutputOptimization.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.indexes.models; - -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * Procedural optimizations the agent should perform during retrieval. - */ -public final class KnowledgeAgentOutputOptimization extends ExpandableStringEnum { - /** - * Attempt to avoid a model call by issuing the most recent chat message as a direct query. - */ - @Generated - public static final KnowledgeAgentOutputOptimization ATTEMPT_BYPASS_MODEL = fromString("attemptBypassModel"); - - /** - * Creates a new instance of KnowledgeAgentOutputOptimization value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public KnowledgeAgentOutputOptimization() { - } - - /** - * Creates or finds a KnowledgeAgentOutputOptimization from its string representation. - * - * @param name a name to look for. - * @return the corresponding KnowledgeAgentOutputOptimization. - */ - @Generated - public static KnowledgeAgentOutputOptimization fromString(String name) { - return fromString(name, KnowledgeAgentOutputOptimization.class); - } - - /** - * Gets known KnowledgeAgentOutputOptimization values. - * - * @return known KnowledgeAgentOutputOptimization values. - */ - @Generated - public static Collection values() { - return values(KnowledgeAgentOutputOptimization.class); - } -} diff --git a/sdk/search/azure-search-documents/swagger/README.md b/sdk/search/azure-search-documents/swagger/README.md index ffd748333602..8336a868c431 100644 --- a/sdk/search/azure-search-documents/swagger/README.md +++ b/sdk/search/azure-search-documents/swagger/README.md @@ -108,7 +108,7 @@ input-file: - https://raw.githubusercontent.com/Azure/azure-rest-api-specs/e078973418d713e01edf3585f95d3378fc6f67c8/specification/search/data-plane/Azure.Search/preview/2025-08-01-preview/searchservice.json models-subpackage: models custom-types-subpackage: implementation.models -custom-types: AnalyzeRequest,AnalyzeResult,AzureActiveDirectoryApplicationCredentials,DataSourceCredentials,DocumentKeysOrIds,EdgeNGramTokenFilterV1,EdgeNGramTokenFilterV2,EntityRecognitionSkillV1,EntityRecognitionSkillV3,KeywordTokenizerV1,KeywordTokenizerV2,ListAliasesResult,ListDataSourcesResult,ListIndexersResult,ListIndexesResult,ListSkillsetsResult,ListSynonymMapsResult,LuceneStandardTokenizerV1,LuceneStandardTokenizerV2,NGramTokenFilterV1,NGramTokenFilterV2,RequestOptions,SearchErrorException,SentimentSkillV1,SentimentSkillV3,SkillNames,ErrorAdditionalInfo,ErrorDetail,ErrorResponse,ErrorResponseException +custom-types: AnalyzeRequest,AnalyzeResult,AzureActiveDirectoryApplicationCredentials,DataSourceCredentials,DocumentKeysOrIds,EdgeNGramTokenFilterV1,EdgeNGramTokenFilterV2,EntityRecognitionSkillV1,EntityRecognitionSkillV3,KeywordTokenizerV1,KeywordTokenizerV2,ListAliasesResult,ListDataSourcesResult,ListIndexersResult,ListIndexesResult,ListIndexStatsSummary,ListKnowledgeAgentsResult,ListKnowledgeSourcesResult,ListSkillsetsResult,ListSynonymMapsResult,LuceneStandardTokenizerV1,LuceneStandardTokenizerV2,NGramTokenFilterV1,NGramTokenFilterV2,RequestOptions,SearchErrorException,SentimentSkillV1,SentimentSkillV3,SkillNames,ErrorAdditionalInfo,ErrorDetail,ErrorResponse,ErrorResponseException customization-class: src/main/java/SearchServiceCustomizations.java directive: - rename-model: @@ -487,3 +487,12 @@ directive: transform: > $.required = $.required.filter((required) => required !== "name"); ``` + +### Remove `KnowledgeAgentOutputOptimization` +```yaml $(tag) == 'searchservice' +directive: + - from: swagger-document + where: $.definitions + transform: > + delete $.KnowledgeAgentOutputOptimization; +``` From b07c244a1064ded8664278f1f964e3b44d995574 Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Wed, 13 Aug 2025 12:58:19 -0400 Subject: [PATCH 06/12] Drop the name requirement in createOrUpdate for Knowledge Agent and Source --- .../indexes/SearchIndexAsyncClient.java | 51 +++++++++---------- .../documents/indexes/SearchIndexClient.java | 45 +++++++--------- .../search/documents/KnowledgeAgentTests.java | 2 +- 3 files changed, 44 insertions(+), 54 deletions(-) diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java index 587200c96279..fd752c079453 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java @@ -63,7 +63,8 @@ * *

* A synonym map is service-level object that contains user-defined synonyms. This object is maintained - * independently from search indexes. Once uploaded, you can point any searchable field to the synonym map (one per field). + * independently of search indexes. Once uploaded, you can point any searchable field to the synonym map + * (one per field). *

* *

@@ -1310,7 +1311,6 @@ Mono> createKnowledgeAgentWithResponse(KnowledgeAgent k /** * Creates a new agent or updates an agent if it already exists. * - * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1322,16 +1322,14 @@ Mono> createKnowledgeAgentWithResponse(KnowledgeAgent k * @return the response body on successful completion of {@link Mono}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono createOrUpdateKnowledgeAgent(String agentName, KnowledgeAgent knowledgeAgent, - String ifMatch, String ifNoneMatch) { - return createOrUpdateKnowledgeAgentWithResponse(agentName, knowledgeAgent, ifMatch, ifNoneMatch) - .map(Response::getValue); + public Mono createOrUpdateKnowledgeAgent(KnowledgeAgent knowledgeAgent, String ifMatch, + String ifNoneMatch) { + return createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, ifMatch, ifNoneMatch).map(Response::getValue); } /** * Creates a new agent or updates an agent if it already exists. * - * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1343,17 +1341,18 @@ public Mono createOrUpdateKnowledgeAgent(String agentName, Knowl * @return the response body along with {@link Response} on successful completion of {@link Mono}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> createOrUpdateKnowledgeAgentWithResponse(String agentName, - KnowledgeAgent knowledgeAgent, String ifMatch, String ifNoneMatch) { - return withContext(context -> createOrUpdateKnowledgeAgentWithResponse(agentName, knowledgeAgent, ifMatch, - ifNoneMatch, context)); + public Mono> createOrUpdateKnowledgeAgentWithResponse(KnowledgeAgent knowledgeAgent, + String ifMatch, String ifNoneMatch) { + return withContext( + context -> createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, ifMatch, ifNoneMatch, context)); } - Mono> createOrUpdateKnowledgeAgentWithResponse(String agentName, - KnowledgeAgent knowledgeAgent, String ifMatch, String ifNoneMatch, Context context) { + Mono> createOrUpdateKnowledgeAgentWithResponse(KnowledgeAgent knowledgeAgent, + String ifMatch, String ifNoneMatch, Context context) { try { return restClient.getKnowledgeAgents() - .createOrUpdateWithResponseAsync(agentName, knowledgeAgent, ifMatch, null, null, context) + .createOrUpdateWithResponseAsync(knowledgeAgent.getName(), knowledgeAgent, ifMatch, ifNoneMatch, null, + context) .onErrorMap(MappingUtils::exceptionMapper); } catch (RuntimeException ex) { return monoError(LOGGER, ex); @@ -1505,7 +1504,6 @@ Mono> createKnowledgeSourceWithResponse(KnowledgeSourc /** * Creates or updates a knowledge source. * - * @param sourceName The name of the knowledge source to create or update. * @param knowledgeSource The definition of the knowledge source to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1517,16 +1515,14 @@ Mono> createKnowledgeSourceWithResponse(KnowledgeSourc * @return A {@link Mono} that will produce the created or updated knowledge source. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono createOrUpdateKnowledgeSource(String sourceName, KnowledgeSource knowledgeSource, - String ifMatch, String ifNoneMatch) { - return createOrUpdateKnowledgeSourceWithResponse(sourceName, knowledgeSource, ifMatch, ifNoneMatch) - .map(Response::getValue); + public Mono createOrUpdateKnowledgeSource(KnowledgeSource knowledgeSource, String ifMatch, + String ifNoneMatch) { + return createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, ifMatch, ifNoneMatch).map(Response::getValue); } /** * Creates or updates a knowledge source. * - * @param sourceName The name of the knowledge source to create or update. * @param knowledgeSource The definition of the knowledge source to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1538,17 +1534,18 @@ public Mono createOrUpdateKnowledgeSource(String sourceName, Kn * @return A {@link Mono} that produces a {@link Response} containing the created or updated knowledge source. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> createOrUpdateKnowledgeSourceWithResponse(String sourceName, - KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch) { - return withContext(context -> createOrUpdateKnowledgeSourceWithResponse(sourceName, knowledgeSource, ifMatch, - ifNoneMatch, context)); + public Mono> createOrUpdateKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, + String ifMatch, String ifNoneMatch) { + return withContext( + context -> createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, ifMatch, ifNoneMatch, context)); } - Mono> createOrUpdateKnowledgeSourceWithResponse(String sourceName, - KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch, Context context) { + Mono> createOrUpdateKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, + String ifMatch, String ifNoneMatch, Context context) { try { return restClient.getKnowledgeSources() - .createOrUpdateWithResponseAsync(sourceName, knowledgeSource, ifMatch, null, null, context) + .createOrUpdateWithResponseAsync(knowledgeSource.getName(), knowledgeSource, ifMatch, ifNoneMatch, null, + context) .onErrorMap(MappingUtils::exceptionMapper); } catch (RuntimeException ex) { return monoError(LOGGER, ex); diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java index aa3daa557cdd..7984b3d1855a 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java @@ -59,7 +59,8 @@ * *

* A synonym map is service-level object that contains user-defined synonyms. This object is maintained - * independently from search indexes. Once uploaded, you can point any searchable field to the synonym map (one per field). + * independently of search indexes. Once uploaded, you can point any searchable field to the synonym map + * (one per field). *

* *

@@ -1344,7 +1345,6 @@ public Response createKnowledgeAgentWithResponse(KnowledgeAgent /** * Creates a new agent or updates an agent if it already exists. * - * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1356,16 +1356,14 @@ public Response createKnowledgeAgentWithResponse(KnowledgeAgent * @return the response. */ @ServiceMethod(returns = ReturnType.SINGLE) - public KnowledgeAgent createOrUpdateKnowledgeAgent(String agentName, KnowledgeAgent knowledgeAgent, String ifMatch, + public KnowledgeAgent createOrUpdateKnowledgeAgent(KnowledgeAgent knowledgeAgent, String ifMatch, String ifNoneMatch) { - return createOrUpdateKnowledgeAgentWithResponse(agentName, knowledgeAgent, ifMatch, ifNoneMatch, Context.NONE) - .getValue(); + return createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, ifMatch, ifNoneMatch, Context.NONE).getValue(); } /** * Creates a new agent or updates an agent if it already exists. * - * @param agentName The name of the agent to create or update. * @param knowledgeAgent The definition of the agent to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1378,13 +1376,11 @@ public KnowledgeAgent createOrUpdateKnowledgeAgent(String agentName, KnowledgeAg * @return the response body along with {@link Response}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Response createOrUpdateKnowledgeAgentWithResponse(String agentName, - KnowledgeAgent knowledgeAgent, String ifMatch, String ifNoneMatch, Context context) { - return Utility - .executeRestCallWithExceptionHandling( - () -> restClient.getKnowledgeAgents() - .createOrUpdateWithResponse(agentName, knowledgeAgent, ifMatch, ifNoneMatch, null, context), - LOGGER); + public Response createOrUpdateKnowledgeAgentWithResponse(KnowledgeAgent knowledgeAgent, + String ifMatch, String ifNoneMatch, Context context) { + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getKnowledgeAgents() + .createOrUpdateWithResponse(knowledgeAgent.getName(), knowledgeAgent, ifMatch, ifNoneMatch, null, context), + LOGGER); } /** @@ -1519,7 +1515,6 @@ public Response createKnowledgeSourceWithResponse(KnowledgeSour /** * Creates or updates a knowledge source. * - * @param sourceName The name of the source to create or update. * @param knowledgeSource The definition of the knowledge source to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1531,16 +1526,15 @@ public Response createKnowledgeSourceWithResponse(KnowledgeSour * @return The created or updated knowledge source. */ @ServiceMethod(returns = ReturnType.SINGLE) - public KnowledgeSource createOrUpdateKnowledgeSource(String sourceName, KnowledgeSource knowledgeSource, - String ifMatch, String ifNoneMatch) { - return createOrUpdateKnowledgeSourceWithResponse(sourceName, knowledgeSource, ifMatch, ifNoneMatch, - Context.NONE).getValue(); + public KnowledgeSource createOrUpdateKnowledgeSource(KnowledgeSource knowledgeSource, String ifMatch, + String ifNoneMatch) { + return createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, ifMatch, ifNoneMatch, Context.NONE) + .getValue(); } /** * Creates or updates a knowledge source. * - * @param sourceName The name of the source to create or update. * @param knowledgeSource The definition of the knowledge source to create or update. * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server * matches this value. @@ -1553,13 +1547,12 @@ public KnowledgeSource createOrUpdateKnowledgeSource(String sourceName, Knowledg * @return A {@link Response} containing the created or updated knowledge source. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Response createOrUpdateKnowledgeSourceWithResponse(String sourceName, - KnowledgeSource knowledgeSource, String ifMatch, String ifNoneMatch, Context context) { - return Utility - .executeRestCallWithExceptionHandling( - () -> restClient.getKnowledgeSources() - .createOrUpdateWithResponse(sourceName, knowledgeSource, ifMatch, ifNoneMatch, null, context), - LOGGER); + public Response createOrUpdateKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, + String ifMatch, String ifNoneMatch, Context context) { + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getKnowledgeSources() + .createOrUpdateWithResponse(knowledgeSource.getName(), knowledgeSource, ifMatch, ifNoneMatch, null, + context), + LOGGER); } /** diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java index 42218de14c0f..809814b8cdde 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java @@ -156,7 +156,7 @@ public void testUpdateKnowledgeAgent() { searchIndexClient.createKnowledgeAgent(knowledgeAgent); String newDescription = "Updated description"; knowledgeAgent.setDescription(newDescription); - searchIndexClient.createOrUpdateKnowledgeAgent(knowledgeAgent.getName(), knowledgeAgent, null, null); + searchIndexClient.createOrUpdateKnowledgeAgent(knowledgeAgent, null, null); KnowledgeAgent retrieved = searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName()); assertEquals(newDescription, retrieved.getDescription()); } From 2d9e27772e5fb274df5950277a42e22c62aaebef Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Thu, 28 Aug 2025 14:29:35 -0400 Subject: [PATCH 07/12] Checkpointing work on resource deployment --- .../documents/SearchServiceVersion.java | 6 +- .../indexes/SearchIndexAsyncClient.java | 92 +-- .../documents/indexes/SearchIndexClient.java | 76 +-- .../search/documents/VectorSearchExample.java | 4 +- .../search/documents/GeographyPointTests.java | 2 +- .../azure/search/documents/IndexingTests.java | 6 +- .../search/documents/KnowledgeAgentTests.java | 342 +++++++++- .../documents/KnowledgeSourceTests.java | 290 ++++++++ .../documents/SearchClientBuilderTests.java | 3 +- ...SearchIndexingBufferedSenderUnitTests.java | 11 +- .../search/documents/SearchTestBase.java | 126 ++-- .../azure/search/documents/SearchTests.java | 6 +- .../documents/SuggestOptionsHandlerTests.java | 2 +- .../azure/search/documents/TestHelpers.java | 10 +- .../search/documents/VectorSearchTests.java | 578 +--------------- .../VectorSearchWithSharedIndexTests.java | 636 ++++++++++++++++++ .../models/IndexActionTests.java | 11 +- .../documents/indexes/DataSourceTests.java | 4 +- .../indexes/IndexManagementTests.java | 8 +- .../indexes/IndexersManagementTests.java | 22 +- .../indexes/SkillsetManagementTests.java | 3 - .../indexes/SynonymMapManagementTests.java | 2 +- .../models/IndexBatchExceptionTests.java | 12 +- sdk/search/test-resources.bicep | 229 +++++-- 24 files changed, 1632 insertions(+), 849 deletions(-) create mode 100644 sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java create mode 100644 sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java index d74ba368209c..5498815f327b 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchServiceVersion.java @@ -25,9 +25,9 @@ public enum SearchServiceVersion implements ServiceVersion { V2024_07_01("2024-07-01"), /** - * {@code 2025-05-01-preview} service version. + * {@code 2025-08-01-preview} service version. */ - V2025_05_01_PREVIEW("2025-05-01-preview"); + V2025_08_01_PREVIEW("2025-08-01-preview"); private final String version; @@ -49,6 +49,6 @@ public String getVersion() { * @return The latest version supported by this client library. */ public static SearchServiceVersion getLatest() { - return V2025_05_01_PREVIEW; + return V2025_08_01_PREVIEW; } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java index fd752c079453..5ee1a9b43744 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java @@ -6,6 +6,7 @@ import com.azure.core.annotation.ServiceClient; import com.azure.core.annotation.ServiceMethod; import com.azure.core.http.HttpPipeline; +import com.azure.core.http.MatchConditions; import com.azure.core.http.rest.PagedFlux; import com.azure.core.http.rest.PagedResponse; import com.azure.core.http.rest.Response; @@ -1312,29 +1313,22 @@ Mono> createKnowledgeAgentWithResponse(KnowledgeAgent k * Creates a new agent or updates an agent if it already exists. * * @param knowledgeAgent The definition of the agent to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the response body on successful completion of {@link Mono}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono createOrUpdateKnowledgeAgent(KnowledgeAgent knowledgeAgent, String ifMatch, - String ifNoneMatch) { - return createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, ifMatch, ifNoneMatch).map(Response::getValue); + public Mono createOrUpdateKnowledgeAgent(KnowledgeAgent knowledgeAgent) { + return createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, null).map(Response::getValue); } /** * Creates a new agent or updates an agent if it already exists. * * @param knowledgeAgent The definition of the agent to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. @@ -1342,14 +1336,16 @@ public Mono createOrUpdateKnowledgeAgent(KnowledgeAgent knowledg */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> createOrUpdateKnowledgeAgentWithResponse(KnowledgeAgent knowledgeAgent, - String ifMatch, String ifNoneMatch) { + MatchConditions matchConditions) { return withContext( - context -> createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, ifMatch, ifNoneMatch, context)); + context -> createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, matchConditions, context)); } Mono> createOrUpdateKnowledgeAgentWithResponse(KnowledgeAgent knowledgeAgent, - String ifMatch, String ifNoneMatch, Context context) { + MatchConditions matchConditions, Context context) { try { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return restClient.getKnowledgeAgents() .createOrUpdateWithResponseAsync(knowledgeAgent.getName(), knowledgeAgent, ifMatch, ifNoneMatch, null, context) @@ -1419,41 +1415,37 @@ public PagedFlux listKnowledgeAgents() { * Deletes an existing agent. * * @param agentName The name of the agent to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return A {@link Mono} that completes when a successful response is received. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono deleteKnowledgeAgent(String agentName, String ifMatch, String ifNoneMatch) { - return deleteKnowledgeAgentWithResponse(agentName, ifMatch, ifNoneMatch).flatMap(FluxUtil::toMono); + public Mono deleteKnowledgeAgent(String agentName) { + return deleteKnowledgeAgentWithResponse(agentName, null).flatMap(FluxUtil::toMono); } /** * Deletes an existing agent. * * @param agentName The name of the agent to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the {@link Response} on successful completion of {@link Mono}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> deleteKnowledgeAgentWithResponse(String agentName, String ifMatch, String ifNoneMatch) { - return withContext(context -> deleteKnowledgeAgentWithResponse(agentName, ifMatch, ifNoneMatch, context)); + public Mono> deleteKnowledgeAgentWithResponse(String agentName, MatchConditions matchConditions) { + return withContext(context -> deleteKnowledgeAgentWithResponse(agentName, matchConditions, context)); } - Mono> deleteKnowledgeAgentWithResponse(String agentName, String ifMatch, String ifNoneMatch, + Mono> deleteKnowledgeAgentWithResponse(String agentName, MatchConditions matchConditions, Context context) { try { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return restClient.getKnowledgeAgents() .deleteWithResponseAsync(agentName, ifMatch, ifNoneMatch, null, context) .onErrorMap(MappingUtils::exceptionMapper); @@ -1505,29 +1497,22 @@ Mono> createKnowledgeSourceWithResponse(KnowledgeSourc * Creates or updates a knowledge source. * * @param knowledgeSource The definition of the knowledge source to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return A {@link Mono} that will produce the created or updated knowledge source. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono createOrUpdateKnowledgeSource(KnowledgeSource knowledgeSource, String ifMatch, - String ifNoneMatch) { - return createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, ifMatch, ifNoneMatch).map(Response::getValue); + public Mono createOrUpdateKnowledgeSource(KnowledgeSource knowledgeSource) { + return createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, null).map(Response::getValue); } /** * Creates or updates a knowledge source. * * @param knowledgeSource The definition of the knowledge source to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. @@ -1535,14 +1520,16 @@ public Mono createOrUpdateKnowledgeSource(KnowledgeSource knowl */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> createOrUpdateKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, - String ifMatch, String ifNoneMatch) { + MatchConditions matchConditions) { return withContext( - context -> createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, ifMatch, ifNoneMatch, context)); + context -> createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, matchConditions, context)); } Mono> createOrUpdateKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, - String ifMatch, String ifNoneMatch, Context context) { + MatchConditions matchConditions, Context context) { try { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return restClient.getKnowledgeSources() .createOrUpdateWithResponseAsync(knowledgeSource.getName(), knowledgeSource, ifMatch, ifNoneMatch, null, context) @@ -1612,42 +1599,37 @@ public PagedFlux listKnowledgeSources() { * Deletes an existing knowledge source. * * @param sourceName The name of the knowledge source to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return A {@link Mono} that completes successfully if the knowledge source was deleted. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono deleteKnowledgeSource(String sourceName, String ifMatch, String ifNoneMatch) { - return deleteKnowledgeAgentWithResponse(sourceName, ifMatch, ifNoneMatch).flatMap(FluxUtil::toMono); + public Mono deleteKnowledgeSource(String sourceName) { + return deleteKnowledgeSourceWithResponse(sourceName, null).flatMap(FluxUtil::toMono); } /** * Deletes an existing knowledge source. * * @param sourceName The name of the knowledge source to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return A {@link Mono} that produces a {@link Response} if the knowledge source was deleted. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> deleteKnowledgeSourceWithResponse(String sourceName, String ifMatch, - String ifNoneMatch) { - return withContext(context -> deleteKnowledgeSourceWithResponse(sourceName, ifMatch, ifNoneMatch, context)); + public Mono> deleteKnowledgeSourceWithResponse(String sourceName, MatchConditions matchConditions) { + return withContext(context -> deleteKnowledgeSourceWithResponse(sourceName, matchConditions, context)); } - Mono> deleteKnowledgeSourceWithResponse(String sourceName, String ifMatch, String ifNoneMatch, + Mono> deleteKnowledgeSourceWithResponse(String sourceName, MatchConditions matchConditions, Context context) { try { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return restClient.getKnowledgeSources() .deleteWithResponseAsync(sourceName, ifMatch, ifNoneMatch, null, context) .onErrorMap(MappingUtils::exceptionMapper); diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java index 7984b3d1855a..054ee0d255b7 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java @@ -6,6 +6,7 @@ import com.azure.core.annotation.ServiceClient; import com.azure.core.annotation.ServiceMethod; import com.azure.core.http.HttpPipeline; +import com.azure.core.http.MatchConditions; import com.azure.core.http.rest.PagedIterable; import com.azure.core.http.rest.PagedResponse; import com.azure.core.http.rest.Response; @@ -1346,29 +1347,22 @@ public Response createKnowledgeAgentWithResponse(KnowledgeAgent * Creates a new agent or updates an agent if it already exists. * * @param knowledgeAgent The definition of the agent to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the response. */ @ServiceMethod(returns = ReturnType.SINGLE) - public KnowledgeAgent createOrUpdateKnowledgeAgent(KnowledgeAgent knowledgeAgent, String ifMatch, - String ifNoneMatch) { - return createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, ifMatch, ifNoneMatch, Context.NONE).getValue(); + public KnowledgeAgent createOrUpdateKnowledgeAgent(KnowledgeAgent knowledgeAgent) { + return createOrUpdateKnowledgeAgentWithResponse(knowledgeAgent, null, Context.NONE).getValue(); } /** * Creates a new agent or updates an agent if it already exists. * * @param knowledgeAgent The definition of the agent to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1377,7 +1371,9 @@ public KnowledgeAgent createOrUpdateKnowledgeAgent(KnowledgeAgent knowledgeAgent */ @ServiceMethod(returns = ReturnType.SINGLE) public Response createOrUpdateKnowledgeAgentWithResponse(KnowledgeAgent knowledgeAgent, - String ifMatch, String ifNoneMatch, Context context) { + MatchConditions matchConditions, Context context) { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return Utility.executeRestCallWithExceptionHandling(() -> restClient.getKnowledgeAgents() .createOrUpdateWithResponse(knowledgeAgent.getName(), knowledgeAgent, ifMatch, ifNoneMatch, null, context), LOGGER); @@ -1446,27 +1442,21 @@ public PagedIterable listKnowledgeAgents(Context context) { * Deletes an existing agent. * * @param agentName The name of the agent to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ @ServiceMethod(returns = ReturnType.SINGLE) - public void deleteKnowledgeAgent(String agentName, String ifMatch, String ifNoneMatch) { - deleteKnowledgeAgentWithResponse(agentName, ifMatch, ifNoneMatch, Context.NONE).getValue(); + public void deleteKnowledgeAgent(String agentName) { + deleteKnowledgeAgentWithResponse(agentName, null, Context.NONE).getValue(); } /** * Deletes an existing agent. * * @param agentName The name of the agent to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1474,8 +1464,10 @@ public void deleteKnowledgeAgent(String agentName, String ifMatch, String ifNone * @return the {@link Response}. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Response deleteKnowledgeAgentWithResponse(String agentName, String ifMatch, String ifNoneMatch, + public Response deleteKnowledgeAgentWithResponse(String agentName, MatchConditions matchConditions, Context context) { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return Utility.executeRestCallWithExceptionHandling( () -> restClient.getKnowledgeAgents().deleteWithResponse(agentName, ifMatch, ifNoneMatch, null, context), LOGGER); @@ -1516,30 +1508,22 @@ public Response createKnowledgeSourceWithResponse(KnowledgeSour * Creates or updates a knowledge source. * * @param knowledgeSource The definition of the knowledge source to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return The created or updated knowledge source. */ @ServiceMethod(returns = ReturnType.SINGLE) - public KnowledgeSource createOrUpdateKnowledgeSource(KnowledgeSource knowledgeSource, String ifMatch, - String ifNoneMatch) { - return createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, ifMatch, ifNoneMatch, Context.NONE) - .getValue(); + public KnowledgeSource createOrUpdateKnowledgeSource(KnowledgeSource knowledgeSource) { + return createOrUpdateKnowledgeSourceWithResponse(knowledgeSource, null, Context.NONE).getValue(); } /** * Creates or updates a knowledge source. * * @param knowledgeSource The definition of the knowledge source to create or update. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1548,7 +1532,9 @@ public KnowledgeSource createOrUpdateKnowledgeSource(KnowledgeSource knowledgeSo */ @ServiceMethod(returns = ReturnType.SINGLE) public Response createOrUpdateKnowledgeSourceWithResponse(KnowledgeSource knowledgeSource, - String ifMatch, String ifNoneMatch, Context context) { + MatchConditions matchConditions, Context context) { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return Utility.executeRestCallWithExceptionHandling(() -> restClient.getKnowledgeSources() .createOrUpdateWithResponse(knowledgeSource.getName(), knowledgeSource, ifMatch, ifNoneMatch, null, context), @@ -1618,27 +1604,21 @@ public PagedIterable listKnowledgeSources(Context context) { * Deletes an existing knowledge agent. * * @param sourceName The name of the knowledge source to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ @ServiceMethod(returns = ReturnType.SINGLE) - public void deleteKnowledgeSource(String sourceName, String ifMatch, String ifNoneMatch) { - deleteKnowledgeSourceWithResponse(sourceName, ifMatch, ifNoneMatch, Context.NONE).getValue(); + public void deleteKnowledgeSource(String sourceName) { + deleteKnowledgeSourceWithResponse(sourceName, null, Context.NONE).getValue(); } /** * Deletes an existing knowledge source. * * @param sourceName The name of the knowledge source to delete. - * @param ifMatch Defines the If-Match condition. The operation will be performed only if the ETag on the server - * matches this value. - * @param ifNoneMatch Defines the If-None-Match condition. The operation will be performed only if the ETag on the - * server does not match this value. + * @param matchConditions Defining {@code If-Match} and {@code If-None-Match} conditions. If null is passed, no + * conditions will be applied. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws ErrorResponseException thrown if the request is rejected by server. @@ -1646,8 +1626,10 @@ public void deleteKnowledgeSource(String sourceName, String ifMatch, String ifNo * @return A {@link Response} indicating deletion completed. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Response deleteKnowledgeSourceWithResponse(String sourceName, String ifMatch, String ifNoneMatch, + public Response deleteKnowledgeSourceWithResponse(String sourceName, MatchConditions matchConditions, Context context) { + String ifMatch = matchConditions != null ? matchConditions.getIfMatch() : null; + String ifNoneMatch = matchConditions != null ? matchConditions.getIfNoneMatch() : null; return Utility.executeRestCallWithExceptionHandling( () -> restClient.getKnowledgeSources().deleteWithResponse(sourceName, ifMatch, ifNoneMatch, null, context), LOGGER); diff --git a/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/VectorSearchExample.java b/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/VectorSearchExample.java index 218fdf6f8c5d..baf426fded00 100644 --- a/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/VectorSearchExample.java +++ b/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/VectorSearchExample.java @@ -54,8 +54,8 @@ *

* This sample is based on the hotels-sample index available to install from the portal with an additional field for * vector description. - *

- * See https://docs.microsoft.com/azure/search/search-get-started-portal + * + * @see Search get started */ public class VectorSearchExample { /** diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/GeographyPointTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/GeographyPointTests.java index 91a40eabc470..5e218d41158b 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/GeographyPointTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/GeographyPointTests.java @@ -66,7 +66,7 @@ private static Map getExpectedDocuments() { @BeforeAll public static void createSharedIndex() { if (TEST_MODE != TestMode.PLAYBACK) { - searchIndexClient = new SearchIndexClientBuilder().endpoint(ENDPOINT) + searchIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .credential(TestHelpers.getTestTokenCredential()) .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) .buildClient(); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/IndexingTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/IndexingTests.java index f04331482623..f5ada36401d4 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/IndexingTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/IndexingTests.java @@ -461,7 +461,7 @@ public void canIndexDynamicDocumentsNotThrowSync() { Response resultResponse = client.indexDocumentsWithResponse(batch, new IndexDocumentsOptions().setThrowOnAnyError(false), Context.NONE); List results = resultResponse.getValue().getResults(); - assertEquals(resultResponse.getStatusCode(), 207); + assertEquals(207, resultResponse.getStatusCode()); assertSuccessfulIndexResult(results.get(0), hotel1Id, 201); assertSuccessfulIndexResult(results.get(1), "randomId", 200); assertFailedIndexResult(results.get(2), "nonExistingHotel", 404); @@ -504,7 +504,7 @@ public void canIndexDynamicDocumentsNotThrowAsync() { asyncClient.indexDocumentsWithResponse(batch, new IndexDocumentsOptions().setThrowOnAnyError(false))) .assertNext(resultResponse -> { List results = resultResponse.getValue().getResults(); - assertEquals(resultResponse.getStatusCode(), 207); + assertEquals(207, resultResponse.getStatusCode()); assertSuccessfulIndexResult(results.get(0), hotel1Id, 201); assertSuccessfulIndexResult(results.get(1), "randomId", 200); assertFailedIndexResult(results.get(2), "nonExistingHotel", 404); @@ -1148,7 +1148,7 @@ void assertSuccessfulIndexResult(IndexingResult result, String key, int statusCo static void assertFailedIndexResult(IndexingResult result, String key, int statusCode) { assertEquals(result.getKey(), key); assertEquals(result.getStatusCode(), statusCode); - assertEquals(result.getErrorMessage(), "Document not found."); + assertEquals("Document not found.", result.getErrorMessage()); assertFalse(result.isSucceeded()); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java index 809814b8cdde..9d1895c1702e 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java @@ -9,6 +9,13 @@ import com.azure.core.test.TestProxyTestBase; import com.azure.json.JsonProviders; import com.azure.json.JsonReader; +import com.azure.search.documents.agents.SearchKnowledgeAgentAsyncClient; +import com.azure.search.documents.agents.SearchKnowledgeAgentClient; +import com.azure.search.documents.agents.models.KnowledgeAgentMessage; +import com.azure.search.documents.agents.models.KnowledgeAgentMessageTextContent; +import com.azure.search.documents.agents.models.KnowledgeAgentRetrievalRequest; +import com.azure.search.documents.agents.models.KnowledgeAgentRetrievalResponse; +import com.azure.search.documents.indexes.SearchIndexAsyncClient; import com.azure.search.documents.indexes.SearchIndexClient; import com.azure.search.documents.indexes.SearchIndexClientBuilder; import com.azure.search.documents.indexes.models.AzureOpenAIModelName; @@ -16,44 +23,52 @@ import com.azure.search.documents.indexes.models.KnowledgeAgent; import com.azure.search.documents.indexes.models.KnowledgeAgentAzureOpenAIModel; import com.azure.search.documents.indexes.models.KnowledgeAgentModel; +import com.azure.search.documents.indexes.models.KnowledgeAgentOutputConfiguration; +import com.azure.search.documents.indexes.models.KnowledgeAgentOutputConfigurationModality; import com.azure.search.documents.indexes.models.KnowledgeSourceReference; import com.azure.search.documents.indexes.models.SearchIndex; -import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSource; -import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSourceParameters; import com.azure.search.documents.indexes.models.SemanticConfiguration; import com.azure.search.documents.indexes.models.SemanticField; import com.azure.search.documents.indexes.models.SemanticPrioritizedFields; import com.azure.search.documents.indexes.models.SemanticSearch; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; +import reactor.test.StepVerifier; import java.io.IOException; import java.io.UncheckedIOException; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; -import static com.azure.search.documents.TestHelpers.HOTEL_INDEX_NAME; import static com.azure.search.documents.TestHelpers.loadResource; import static com.azure.search.documents.TestHelpers.uploadDocumentsJson; import static com.azure.search.documents.TestHelpers.waitForIndexing; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +/** + * Tests for Knowledge Agent operations. + */ @Execution(ExecutionMode.SAME_THREAD) -@Disabled("Disabled until the service is available.") public class KnowledgeAgentTests extends SearchTestBase { - private static final String HOTEL_KNOWLEDGE_SOURCE_NAME = "hotel-knowledge-source"; + private static final String HOTEL_INDEX_NAME = "shared-knowledge-agent-index"; + private static final String HOTEL_KNOWLEDGE_SOURCE_NAME = "shared-knowledge-agent-source"; + private static final KnowledgeAgentAzureOpenAIModel OPEN_AI_AGENT_MODEL = new KnowledgeAgentAzureOpenAIModel( + new AzureOpenAIVectorizerParameters() + .setModelName(AzureOpenAIModelName.fromString(OPENAI_MODEL_NAME)) + .setDeploymentName(OPENAI_DEPLOYMENT_NAME) + .setResourceUrl(OPENAI_ENDPOINT)); private static final List KNOWLEDGE_AGENT_MODELS - = Collections.singletonList(new KnowledgeAgentAzureOpenAIModel( - new AzureOpenAIVectorizerParameters().setModelName(AzureOpenAIModelName.GPT4O) - .setDeploymentName("gpt-35-turbo") - .setApiKey(OPENAI_API_KEY) - .setResourceUrl(OPENAI_API_ENDPOINT))); + = Collections.singletonList(OPEN_AI_AGENT_MODEL); private static final List KNOWLEDGE_SOURCE_REFERENCES = Collections.singletonList(new KnowledgeSourceReference(HOTEL_KNOWLEDGE_SOURCE_NAME)); @@ -69,11 +84,17 @@ public static void setupClass() { } searchIndexClient = setupIndex(); - searchIndexClient.createKnowledgeSource(new SearchIndexKnowledgeSource(HOTEL_KNOWLEDGE_SOURCE_NAME, - new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME))); - waitForIndexing(); + } + + @AfterEach + public void cleanup() { + if (TEST_MODE != TestMode.PLAYBACK) { + // Delete Knowledge Agents created during tests. + searchIndexClient.listKnowledgeAgents() + .forEach(knowledgeAgent -> searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName())); + } } @AfterAll @@ -81,12 +102,7 @@ protected static void cleanupClass() { // Clean up any resources after all tests. if (TEST_MODE != TestMode.PLAYBACK) { // Delete the knowledge source created for the tests. - searchIndexClient.deleteKnowledgeSource("hotel-knowledge-source", null, null); - - // list all remaining knowledge agents and delete them - searchIndexClient.listKnowledgeAgents() - .forEach( - knowledgeAgent -> searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName(), null, null)); + searchIndexClient.deleteKnowledgeSource(HOTEL_KNOWLEDGE_SOURCE_NAME); searchIndexClient.deleteIndex(HOTEL_INDEX_NAME); @@ -99,28 +115,111 @@ protected static void cleanupClass() { } @Test - public void testCreateKnowledgeAgent() { + public void createKnowledgeAgentSync() { // Test creating a knowledge agent. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); - searchIndexClient.createKnowledgeAgent(knowledgeAgent); + KnowledgeAgent created = searchIndexClient.createKnowledgeAgent(knowledgeAgent); + + assertEquals(knowledgeAgent.getName(), created.getName()); + + assertEquals(1, created.getModels().size()); + KnowledgeAgentAzureOpenAIModel createdModel + = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, created.getModels().get(0)); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + createdModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + createdModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + createdModel.getAzureOpenAIParameters().getResourceUrl()); + + assertEquals(1, created.getKnowledgeSources().size()); + assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, created.getKnowledgeSources().get(0).getName()); } @Test - public void testGetKnowledgeAgent() { - // Test getting a knowledge agent. + public void createKnowledgeAgentAsync() { + // Test creating a knowledge agent. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + + StepVerifier.create(searchIndexClient.createKnowledgeAgent(knowledgeAgent)) + .assertNext(created -> { + assertEquals(knowledgeAgent.getName(), created.getName()); + + assertEquals(1, created.getModels().size()); + KnowledgeAgentAzureOpenAIModel createdModel + = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, created.getModels().get(0)); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + createdModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + createdModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + createdModel.getAzureOpenAIParameters().getResourceUrl()); + + assertEquals(1, created.getKnowledgeSources().size()); + assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, created.getKnowledgeSources().get(0).getName()); + }) + .verifyComplete(); + } + @Test + public void getKnowledgeAgentSync() { + // Test getting a knowledge agent. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); + KnowledgeAgent retrieved = searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName()); assertEquals(knowledgeAgent.getName(), retrieved.getName()); + + assertEquals(1, retrieved.getModels().size()); + KnowledgeAgentAzureOpenAIModel retrievedModel + = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, retrieved.getModels().get(0)); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + retrievedModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + retrievedModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + retrievedModel.getAzureOpenAIParameters().getResourceUrl()); + + assertEquals(1, retrieved.getKnowledgeSources().size()); + assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, retrieved.getKnowledgeSources().get(0).getName()); } @Test - public void testListKnowledgeAgents() { + public void getKnowledgeAgentAsync() { + // Test getting a knowledge agent. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); + + StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) + .assertNext(retrieved -> { + assertEquals(knowledgeAgent.getName(), retrieved.getName()); + + assertEquals(1, retrieved.getModels().size()); + KnowledgeAgentAzureOpenAIModel retrievedModel + = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, retrieved.getModels().get(0)); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + retrievedModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + retrievedModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + retrievedModel.getAzureOpenAIParameters().getResourceUrl()); + + assertEquals(1, retrieved.getKnowledgeSources().size()); + assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, retrieved.getKnowledgeSources().get(0).getName()); + }) + .verifyComplete(); + } + + @Test + public void listKnowledgeAgentsSync() { // Test listing knowledge agents. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); long currentCount = searchIndexClient.listKnowledgeAgents().stream().count(); @@ -130,25 +229,73 @@ public void testListKnowledgeAgents() { = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); searchIndexClient.createKnowledgeAgent(knowledgeAgent2); - long knowledgeAgentCount = searchIndexClient.listKnowledgeAgents().stream().count(); - assertEquals(2 + currentCount, knowledgeAgentCount); + Map knowledgeAgentsByName = searchIndexClient.listKnowledgeAgents().stream() + .collect(Collectors.toMap(KnowledgeAgent::getName, Function.identity())); + + assertEquals(2, knowledgeAgentsByName.size() - currentCount); + KnowledgeAgent listedAgent1 = knowledgeAgentsByName.get(knowledgeAgent.getName()); + assertNotNull(listedAgent1); + KnowledgeAgent listedAgent2 = knowledgeAgentsByName.get(knowledgeAgent2.getName()); + assertNotNull(listedAgent2); } @Test - public void testDeleteKnowledgeAgent() { + public void listKnowledgeAgentsAsync() { + // Test listing knowledge agents. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + long currentCount = searchIndexClient.listKnowledgeAgents().count().block(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + KnowledgeAgent knowledgeAgent2 + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); + searchIndexClient.createKnowledgeAgent(knowledgeAgent2).block(); + + StepVerifier.create(searchIndexClient.listKnowledgeAgents().collectMap(KnowledgeAgent::getName)) + .assertNext(knowledgeAgentsByName -> { + assertEquals(2, knowledgeAgentsByName.size() - currentCount); + KnowledgeAgent listedAgent1 = knowledgeAgentsByName.get(knowledgeAgent.getName()); + assertNotNull(listedAgent1); + KnowledgeAgent listedAgent2 = knowledgeAgentsByName.get(knowledgeAgent2.getName()); + assertNotNull(listedAgent2); + }) + .verifyComplete(); + } + + @Test + public void deleteKnowledgeAgentSync() { // Test deleting a knowledge agent. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); - waitForIndexing(); - assertNotNull(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())); - searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName(), null, null); + + assertEquals(knowledgeAgent.getName(), searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName()).getName()); + searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName()); assertThrows(HttpResponseException.class, () -> searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())); } @Test - public void testUpdateKnowledgeAgent() { + public void deleteKnowledgeAgentAsync() { + // Test deleting a knowledge agent. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); + + StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) + .assertNext(knowledgeAgent1 -> assertEquals(knowledgeAgent.getName(), knowledgeAgent1.getName())) + .verifyComplete(); + + StepVerifier.create(searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName())) + .verifyComplete(); + + StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) + .verifyError(HttpResponseException.class); + } + + @Test + public void updateKnowledgeAgentSync() { // Test updating a knowledge agent. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent @@ -156,11 +303,137 @@ public void testUpdateKnowledgeAgent() { searchIndexClient.createKnowledgeAgent(knowledgeAgent); String newDescription = "Updated description"; knowledgeAgent.setDescription(newDescription); - searchIndexClient.createOrUpdateKnowledgeAgent(knowledgeAgent, null, null); + searchIndexClient.createOrUpdateKnowledgeAgent(knowledgeAgent); KnowledgeAgent retrieved = searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName()); assertEquals(newDescription, retrieved.getDescription()); } + @Test + public void updateKnowledgeAgentAsync() { + // Test updating a knowledge agent. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); + String newDescription = "Updated description"; + knowledgeAgent.setDescription(newDescription); + searchIndexClient.createOrUpdateKnowledgeAgent(knowledgeAgent).block(); + + StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) + .assertNext(retrieved -> assertEquals(newDescription, retrieved.getDescription())) + .verifyComplete(); + } + + @Test + public void basicRetrievalSync() { + // Test knowledge agent retrieval functionality. + SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + searchIndexClient.createKnowledgeAgent(knowledgeAgent); + + SearchKnowledgeAgentClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(true).buildClient(); + + KnowledgeAgentMessageTextContent messageTextContent + = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); + KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) + .setRole("user"); + KnowledgeAgentRetrievalRequest retrievalRequest + = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); + + KnowledgeAgentRetrievalResponse response = knowledgeAgentClient.retrieve(retrievalRequest, null); + assertNotNull(response); + assertNotNull(response.getResponse()); + } + + @Test + public void basicRetrievalAsync() { + // Test knowledge agent retrieval functionality. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); + searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); + + SearchKnowledgeAgentAsyncClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(false) + .buildAsyncClient(); + + KnowledgeAgentMessageTextContent messageTextContent + = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); + KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) + .setRole("user"); + KnowledgeAgentRetrievalRequest retrievalRequest + = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); + + StepVerifier.create(knowledgeAgentClient.retrieve(retrievalRequest, null)) + .assertNext(response -> { + assertNotNull(response); + assertNotNull(response.getResponse()); + }) + .verifyComplete(); + } + + @Test + public void answerSynthesisRetrievalSync() { + // Test knowledge agent retrieval functionality. + SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES) + .setRetrievalInstructions("Only include well reviewed hotels.") + .setOutputConfiguration(new KnowledgeAgentOutputConfiguration() + .setModality(KnowledgeAgentOutputConfigurationModality.ANSWER_SYNTHESIS) + .setAnswerInstructions("Provide a concise answer based on the provided information.") + .setAttemptFastPath(true) + .setIncludeActivity(true)); + searchIndexClient.createKnowledgeAgent(knowledgeAgent); + + SearchKnowledgeAgentClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(true).buildClient(); + + KnowledgeAgentMessageTextContent messageTextContent + = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); + KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) + .setRole("user"); + KnowledgeAgentRetrievalRequest retrievalRequest + = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); + + KnowledgeAgentRetrievalResponse response = knowledgeAgentClient.retrieve(retrievalRequest, null); + assertNotNull(response); + assertNotNull(response.getResponse()); + assertNotNull(response.getActivity()); + } + + @Test + public void answerSynthesisRetrievalAsync() { + // Test knowledge agent retrieval functionality. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeAgent knowledgeAgent + = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES) + .setRetrievalInstructions("Only include well reviewed hotels.") + .setOutputConfiguration(new KnowledgeAgentOutputConfiguration() + .setModality(KnowledgeAgentOutputConfigurationModality.ANSWER_SYNTHESIS) + .setAnswerInstructions("Provide a concise answer based on the provided information.") + .setAttemptFastPath(true) + .setIncludeActivity(true)); + searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); + + SearchKnowledgeAgentAsyncClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(false) + .buildAsyncClient(); + + KnowledgeAgentMessageTextContent messageTextContent + = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); + KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) + .setRole("user"); + KnowledgeAgentRetrievalRequest retrievalRequest + = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); + + StepVerifier.create(knowledgeAgentClient.retrieve(retrievalRequest, null)) + .assertNext(response -> { + assertNotNull(response); + assertNotNull(response.getResponse()); + assertNotNull(response.getActivity()); + }) + .verifyComplete(); + } + private String randomKnowledgeAgentName() { // Generate a random name for the knowledge agent. return testResourceNamer.randomName("knowledge-agent-", 63); @@ -170,7 +443,7 @@ private static SearchIndexClient setupIndex() { try (JsonReader jsonReader = JsonProviders.createReader(loadResource(HOTELS_TESTS_INDEX_DATA_JSON))) { SearchIndex baseIndex = SearchIndex.fromJson(jsonReader); - SearchIndexClient searchIndexClient = new SearchIndexClientBuilder().endpoint(ENDPOINT) + SearchIndexClient searchIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) .credential(TestHelpers.getTestTokenCredential()) .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) @@ -193,5 +466,4 @@ private static SearchIndexClient setupIndex() { throw new UncheckedIOException(ex); } } - } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java new file mode 100644 index 000000000000..d2daab9c978f --- /dev/null +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java @@ -0,0 +1,290 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.search.documents; + +import com.azure.core.exception.HttpResponseException; +import com.azure.core.http.policy.HttpLogDetailLevel; +import com.azure.core.http.policy.HttpLogOptions; +import com.azure.core.test.TestMode; +import com.azure.core.test.TestProxyTestBase; +import com.azure.json.JsonProviders; +import com.azure.json.JsonReader; +import com.azure.search.documents.indexes.SearchIndexAsyncClient; +import com.azure.search.documents.indexes.SearchIndexClient; +import com.azure.search.documents.indexes.SearchIndexClientBuilder; +import com.azure.search.documents.indexes.models.KnowledgeSource; +import com.azure.search.documents.indexes.models.SearchIndex; +import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSource; +import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSourceParameters; +import com.azure.search.documents.indexes.models.SemanticConfiguration; +import com.azure.search.documents.indexes.models.SemanticField; +import com.azure.search.documents.indexes.models.SemanticPrioritizedFields; +import com.azure.search.documents.indexes.models.SemanticSearch; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import reactor.test.StepVerifier; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static com.azure.search.documents.TestHelpers.loadResource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Tests for Knowledge Source operations. + */ +@Execution(ExecutionMode.SAME_THREAD) +public class KnowledgeSourceTests extends SearchTestBase { + private static final String HOTEL_INDEX_NAME = "shared-knowledge-source-index"; + private static SearchIndexClient searchIndexClient; + + @BeforeAll + public static void setupClass() { + // Set up any necessary configurations or resources before all tests. + TestProxyTestBase.setupClass(); + + if (TEST_MODE == TestMode.PLAYBACK) { + return; + } + + searchIndexClient = setupIndex(); + } + + @AfterEach + public void cleanup() { + if (TEST_MODE != TestMode.PLAYBACK) { + // Delete Knowledge Sources created during tests. + searchIndexClient.listKnowledgeSources() + .forEach(knowledgeSource -> searchIndexClient.deleteKnowledgeSource(knowledgeSource.getName())); + } + } + + @AfterAll + protected static void cleanupClass() { + // Clean up any resources after all tests. + if (TEST_MODE != TestMode.PLAYBACK) { + searchIndexClient.deleteIndex(HOTEL_INDEX_NAME); + + try { + Thread.sleep(5000); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + } + } + + @Test + public void createKnowledgeSourceSync() { + // Test creating a knowledge source. + SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + + KnowledgeSource created = searchIndexClient.createKnowledgeSource(knowledgeSource); + + assertEquals(knowledgeSource.getName(), created.getName()); + + SearchIndexKnowledgeSource createdSource = assertInstanceOf(SearchIndexKnowledgeSource.class, created); + assertEquals(HOTEL_INDEX_NAME, createdSource.getSearchIndexParameters().getSearchIndexName()); + } + + @Test + public void createKnowledgeSourceAsync() { + // Test creating a knowledge source. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + + StepVerifier.create(searchIndexClient.createKnowledgeSource(knowledgeSource)) + .assertNext(created -> { + assertEquals(knowledgeSource.getName(), created.getName()); + + SearchIndexKnowledgeSource createdSource = assertInstanceOf(SearchIndexKnowledgeSource.class, created); + assertEquals(HOTEL_INDEX_NAME, createdSource.getSearchIndexParameters().getSearchIndexName()); + }) + .verifyComplete(); + } + + @Test + public void getKnowledgeSourceSync() { + // Test getting a knowledge source. + SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource); + + KnowledgeSource retrieved = searchIndexClient.getKnowledgeSource(knowledgeSource.getName()); + assertEquals(knowledgeSource.getName(), retrieved.getName()); + + SearchIndexKnowledgeSource retrievedSource = assertInstanceOf(SearchIndexKnowledgeSource.class, retrieved); + assertEquals(HOTEL_INDEX_NAME, retrievedSource.getSearchIndexParameters().getSearchIndexName()); + } + + @Test + public void getKnowledgeSourceAsync() { + // Test getting a knowledge source. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource).block(); + + StepVerifier.create(searchIndexClient.getKnowledgeSource(knowledgeSource.getName())) + .assertNext(retrieved -> { + assertEquals(knowledgeSource.getName(), retrieved.getName()); + + SearchIndexKnowledgeSource retrievedSource = assertInstanceOf(SearchIndexKnowledgeSource.class, retrieved); + assertEquals(HOTEL_INDEX_NAME, retrievedSource.getSearchIndexParameters().getSearchIndexName()); + }) + .verifyComplete(); + } + + @Test + public void listKnowledgeSourcesSync() { + // Test listing knowledge sources. + SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); + long currentCount = searchIndexClient.listKnowledgeSources().stream().count(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + KnowledgeSource knowledgeSource2 = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource); + searchIndexClient.createKnowledgeSource(knowledgeSource2); + Map knowledgeSourcesByName = searchIndexClient.listKnowledgeSources().stream() + .collect(Collectors.toMap(KnowledgeSource::getName, Function.identity())); + + assertEquals(2, knowledgeSourcesByName.size() - currentCount); + KnowledgeSource listedSource = knowledgeSourcesByName.get(knowledgeSource.getName()); + assertNotNull(listedSource); + KnowledgeSource listedSource2 = knowledgeSourcesByName.get(knowledgeSource2.getName()); + assertNotNull(listedSource2); + } + + @Test + public void listKnowledgeSourceAsync() { + // Test listing knowledge sources. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + long currentCount = searchIndexClient.listKnowledgeSources().count().block(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + KnowledgeSource knowledgeSource2 = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource).block(); + searchIndexClient.createKnowledgeSource(knowledgeSource2).block(); + + StepVerifier.create(searchIndexClient.listKnowledgeSources().collectMap(KnowledgeSource::getName)) + .assertNext(knowledgeSourcesByName -> { + assertEquals(2, knowledgeSourcesByName.size() - currentCount); + KnowledgeSource listedSource = knowledgeSourcesByName.get(knowledgeSource.getName()); + assertNotNull(listedSource); + KnowledgeSource listedSource2 = knowledgeSourcesByName.get(knowledgeSource2.getName()); + assertNotNull(listedSource2); + }) + .verifyComplete(); + } + + @Test + public void deleteKnowledgeSourceSync() { + // Test deleting a knowledge source. + SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource); + + assertEquals(knowledgeSource.getName(), + searchIndexClient.getKnowledgeSource(knowledgeSource.getName()).getName()); + searchIndexClient.deleteKnowledgeSource(knowledgeSource.getName()); + assertThrows(HttpResponseException.class, + () -> searchIndexClient.getKnowledgeSource(knowledgeSource.getName())); + } + + @Test + public void deleteKnowledgeSourceAsync() { + // Test deleting a knowledge source. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource).block(); + + StepVerifier.create(searchIndexClient.getKnowledgeSource(knowledgeSource.getName())) + .assertNext(retrieved -> assertEquals(knowledgeSource.getName(), retrieved.getName())) + .verifyComplete(); + + StepVerifier.create(searchIndexClient.deleteKnowledgeSource(knowledgeSource.getName())).verifyComplete(); + + StepVerifier.create(searchIndexClient.getKnowledgeSource(knowledgeSource.getName())) + .verifyError(HttpResponseException.class); + } + + @Test + public void updateKnowledgeSourceSync() { + // Test updating a knowledge source. + SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource); + String newDescription = "Updated description"; + knowledgeSource.setDescription(newDescription); + searchIndexClient.createOrUpdateKnowledgeSource(knowledgeSource); + KnowledgeSource retrieved = searchIndexClient.getKnowledgeSource(knowledgeSource.getName()); + assertEquals(newDescription, retrieved.getDescription()); + } + + @Test + public void updateKnowledgeSourceAsync() { + // Test updating a knowledge source. + SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); + searchIndexClient.createKnowledgeSource(knowledgeSource).block(); + String newDescription = "Updated description"; + knowledgeSource.setDescription(newDescription); + searchIndexClient.createOrUpdateKnowledgeSource(knowledgeSource).block(); + + StepVerifier.create(searchIndexClient.getKnowledgeSource(knowledgeSource.getName())) + .assertNext(retrieved -> assertEquals(newDescription, retrieved.getDescription())) + .verifyComplete(); + } + + private String randomKnowledgeSourceName() { + // Generate a random name for the knowledge source. + return testResourceNamer.randomName("knowledge-source-", 63); + } + + private static SearchIndexClient setupIndex() { + try (JsonReader jsonReader = JsonProviders.createReader(loadResource(HOTELS_TESTS_INDEX_DATA_JSON))) { + SearchIndex baseIndex = SearchIndex.fromJson(jsonReader); + + SearchIndexClient searchIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) + .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) + .credential(TestHelpers.getTestTokenCredential()) + .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) + .buildClient(); + + List semanticConfigurations + = Collections.singletonList(new SemanticConfiguration("semantic-config", + new SemanticPrioritizedFields().setTitleField(new SemanticField("HotelName")) + .setContentFields(new SemanticField("Description")) + .setKeywordsFields(new SemanticField("Category")))); + SemanticSearch semanticSearch = new SemanticSearch().setDefaultConfigurationName("semantic-config") + .setConfigurations(semanticConfigurations); + searchIndexClient.createOrUpdateIndex( + TestHelpers.createTestIndex(HOTEL_INDEX_NAME, baseIndex).setSemanticSearch(semanticSearch)); + + return searchIndexClient; + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } +} diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchClientBuilderTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchClientBuilderTests.java index 627a22332731..a75e198554b8 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchClientBuilderTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchClientBuilderTests.java @@ -5,6 +5,7 @@ import com.azure.core.credential.AzureKeyCredential; import com.azure.core.exception.HttpResponseException; +import com.azure.core.http.HttpHeaderName; import com.azure.core.http.policy.ExponentialBackoffOptions; import com.azure.core.http.policy.FixedDelay; import com.azure.core.http.policy.FixedDelayOptions; @@ -192,7 +193,7 @@ public void clientOptionHeadersAreAddedLast() { new ClientOptions().setHeaders(Collections.singletonList(new Header("User-Agent", "custom")))) .retryPolicy(new RetryPolicy(new FixedDelay(3, Duration.ofMillis(1)))) .httpClient(httpRequest -> { - assertEquals("custom", httpRequest.getHeaders().getValue("User-Agent")); + assertEquals("custom", httpRequest.getHeaders().getValue(HttpHeaderName.USER_AGENT)); return Mono.just(new MockHttpResponse(httpRequest, 400)); }) .buildClient(); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java index 8929dd156537..a43d207f4b91 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java @@ -48,7 +48,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static com.azure.search.documents.SearchTestBase.ENDPOINT; +import static com.azure.search.documents.SearchTestBase.SEARCH_ENDPOINT; import static com.azure.search.documents.SearchTestBase.HOTELS_DATA_JSON; import static com.azure.search.documents.TestHelpers.getTestTokenCredential; import static com.azure.search.documents.TestHelpers.readJsonFileToList; @@ -71,7 +71,7 @@ public class SearchIndexingBufferedSenderUnitTests { } private static SearchClientBuilder getSearchClientBuilder() { - return new SearchClientBuilder().endpoint(ENDPOINT).indexName("index").credential(getTestTokenCredential()); + return new SearchClientBuilder().endpoint(SEARCH_ENDPOINT).indexName("index").credential(getTestTokenCredential()); } private static HttpClient wrapWithAsserting(HttpClient wrappedHttpClient, boolean isSync) { @@ -1093,12 +1093,11 @@ public void concurrentFlushesOnlyAllowsOneProcessorAsync() throws InterruptedExc batchingClient.addUploadActions(readJsonFileToList(HOTELS_DATA_JSON)).block(); AtomicLong firstFlushCompletionTime = new AtomicLong(); - SharedExecutorService.getInstance().execute(() -> { - Mono.using(() -> 1, ignored -> batchingClient.flush(), ignored -> { + SharedExecutorService.getInstance() + .execute(() -> Mono.using(() -> 1, ignored -> batchingClient.flush(), ignored -> { firstFlushCompletionTime.set(System.currentTimeMillis()); countDownLatch.countDown(); - }).block(); - }); + }).block()); // Delay the second flush by 100ms to ensure that it starts after the first flush. // The mocked HttpRequest will delay the response by 2 seconds, so if the second flush does finish first it will diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java index cc2868f5bb85..f09ae3680111 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java @@ -7,7 +7,9 @@ import com.azure.core.credential.TokenCredential; import com.azure.core.http.HttpClient; import com.azure.core.http.policy.FixedDelay; +import com.azure.core.http.policy.FixedDelayOptions; import com.azure.core.http.policy.HttpPipelinePolicy; +import com.azure.core.http.policy.RetryOptions; import com.azure.core.http.policy.RetryPolicy; import com.azure.core.test.InterceptorManager; import com.azure.core.test.TestMode; @@ -17,6 +19,7 @@ import com.azure.core.util.logging.ClientLogger; import com.azure.json.JsonProviders; import com.azure.json.JsonReader; +import com.azure.search.documents.agents.SearchKnowledgeAgentClientBuilder; import com.azure.search.documents.indexes.SearchIndexClientBuilder; import com.azure.search.documents.indexes.SearchIndexerClientBuilder; import com.azure.search.documents.indexes.SearchIndexerDataSources; @@ -38,7 +41,6 @@ import com.azure.search.documents.indexes.models.SearchIndex; import com.azure.search.documents.indexes.models.SearchIndexerDataSourceConnection; import com.azure.search.documents.indexes.models.SearchSuggester; -import com.azure.search.documents.indexes.models.SoftDeleteColumnDeletionDetectionPolicy; import com.azure.search.documents.indexes.models.TagScoringFunction; import com.azure.search.documents.indexes.models.TagScoringParameters; import com.azure.search.documents.indexes.models.TextWeights; @@ -58,7 +60,6 @@ import java.util.TimeZone; import java.util.function.BiConsumer; -import static com.azure.search.documents.TestHelpers.BLOB_DATASOURCE_NAME; import static com.azure.search.documents.TestHelpers.HOTEL_INDEX_NAME; import static com.azure.search.documents.TestHelpers.ISO8601_FORMAT; import static com.azure.search.documents.TestHelpers.SQL_DATASOURCE_NAME; @@ -74,19 +75,25 @@ public abstract class SearchTestBase extends TestProxyTestBase { protected static final String HOTELS_TESTS_INDEX_DATA_JSON = "HotelsTestsIndexData.json"; private boolean sanitizersRemoved = false; - protected static final String ENDPOINT + protected static final String SEARCH_ENDPOINT = Configuration.getGlobalConfiguration().get("SEARCH_SERVICE_ENDPOINT", "https://playback.search.windows.net"); - protected static final String STORAGE_CONNECTION_STRING - = Configuration.getGlobalConfiguration().get("SEARCH_STORAGE_CONNECTION_STRING", "connectionString"); + protected static final String OPENAI_ENDPOINT = Configuration.getGlobalConfiguration() + .get("SEARCH_OPENAI_ENDPOINT", "https://your-endpoint.openai.azure.com"); + protected static final String OPENAI_DEPLOYMENT_NAME = Configuration.getGlobalConfiguration() + .get("SEARCH_OPENAI_DEPLOYMENT_NAME", "deployment-name"); + protected static final String OPENAI_MODEL_NAME = Configuration.getGlobalConfiguration() + .get("SEARCH_OPENAI_MODEL_NAME", "model-name"); - protected static final String OPENAI_API_KEY - = Configuration.getGlobalConfiguration().get("AZURE_OPENAI_API_KEY", "your-api-key"); + protected static final String STORAGE_ACCOUNT_NAME = Configuration.getGlobalConfiguration() + .get("SEARCH_STORAGE_ACCOUNT_NAME", "storageaccount"); + protected static final String BLOB_CONTAINER_NAME = Configuration.getGlobalConfiguration() + .get("SEARCH_STORAGE_CONTAINER_NAME", "searchcontainer"); - protected static final String OPENAI_API_ENDPOINT = Configuration.getGlobalConfiguration() - .get("AZURE_OPENAI_API_ENDPOINT", "https://your-endpoint.openai.azure.com"); - - protected static final String BLOB_CONTAINER_NAME = "searchcontainer"; + protected static final String SUBSCRIPTION_ID = Configuration.getGlobalConfiguration() + .get(Configuration.PROPERTY_AZURE_SUBSCRIPTION_ID, "subscription-id"); + protected static final String RESOURCE_GROUP = Configuration.getGlobalConfiguration() + .get(Configuration.PROPERTY_AZURE_RESOURCE_GROUP, "resource-group"); protected static final TestMode TEST_MODE = initializeTestMode(); @@ -98,17 +105,16 @@ public abstract class SearchTestBase extends TestProxyTestBase { // Change the delay based on the mode. static final RetryPolicy SERVICE_THROTTLE_SAFE_RETRY_POLICY = new RetryPolicy( new FixedDelay(4, TEST_MODE == TestMode.PLAYBACK ? Duration.ofMillis(1) : Duration.ofSeconds(60))); + static final RetryOptions SERVICE_THROTTLE_SAFE_RETRY_OPTIONS = new RetryOptions(new FixedDelayOptions(4, + TEST_MODE == TestMode.PLAYBACK ? Duration.ofMillis(1) : Duration.ofSeconds(60))); protected String createHotelIndex() { - return setupIndexFromJsonFile(HOTELS_TESTS_INDEX_DATA_JSON); - } - - protected InterceptorManager getInterceptorManager() { - return interceptorManager; + return setupIndexFromJsonFile(); } - protected String setupIndexFromJsonFile(String jsonFile) { - try (JsonReader jsonReader = JsonProviders.createReader(TestHelpers.loadResource(jsonFile))) { + protected String setupIndexFromJsonFile() { + try (JsonReader jsonReader + = JsonProviders.createReader(TestHelpers.loadResource(SearchTestBase.HOTELS_TESTS_INDEX_DATA_JSON))) { SearchIndex baseIndex = SearchIndex.fromJson(jsonReader); String testIndexName = testResourceNamer.randomName(baseIndex.getName(), 64); @@ -125,9 +131,9 @@ protected String setupIndex(SearchIndex index) { } protected SearchIndexClientBuilder getSearchIndexClientBuilder(boolean isSync) { - SearchIndexClientBuilder builder = new SearchIndexClientBuilder().endpoint(ENDPOINT) - .credential(getTestTokenCredential(interceptorManager)) - .httpClient(getHttpClient(true, interceptorManager, isSync)) + SearchIndexClientBuilder builder = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) + .credential(getTestTokenCredential()) + .httpClient(getHttpClient(interceptorManager, isSync)) .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY); // Disable `("$..token")` and `name` sanitizer @@ -146,13 +152,12 @@ protected SearchIndexClientBuilder getSearchIndexClientBuilder(boolean isSync) { } return builder; - } protected SearchIndexerClientBuilder getSearchIndexerClientBuilder(boolean isSync, HttpPipelinePolicy... policies) { - SearchIndexerClientBuilder builder = new SearchIndexerClientBuilder().endpoint(ENDPOINT) - .credential(getTestTokenCredential(interceptorManager)) - .httpClient(getHttpClient(true, interceptorManager, isSync)) + SearchIndexerClientBuilder builder = new SearchIndexerClientBuilder().endpoint(SEARCH_ENDPOINT) + .credential(getTestTokenCredential()) + .httpClient(getHttpClient(interceptorManager, isSync)) .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY); addPolicies(builder, policies); @@ -171,7 +176,30 @@ protected SearchIndexerClientBuilder getSearchIndexerClientBuilder(boolean isSyn } return builder; + } + + protected SearchKnowledgeAgentClientBuilder getSearchKnowledgeAgentClientBuilder(boolean isSync) { + SearchKnowledgeAgentClientBuilder builder = new SearchKnowledgeAgentClientBuilder().endpoint(SEARCH_ENDPOINT) + .credential(getTestTokenCredential()) + .httpClient(getHttpClient(interceptorManager, isSync)) + .retryOptions(SERVICE_THROTTLE_SAFE_RETRY_OPTIONS); + + // Disable `("$..token")` and `name` sanitizer + if (!interceptorManager.isLiveMode() && !sanitizersRemoved) { + interceptorManager.removeSanitizers("AZSDK3431", "AZSDK3493", "AZSDK3430"); + sanitizersRemoved = true; + } + + if (interceptorManager.isPlaybackMode()) { + addPolicies(builder); + return builder; + } + + if (interceptorManager.isRecordMode()) { + builder.addPolicy(interceptorManager.getRecordPolicy()); + } + return builder; } private static void addPolicies(HttpTrait builder, HttpPipelinePolicy... policies) { @@ -185,30 +213,24 @@ private static void addPolicies(HttpTrait builder, HttpPipelinePolicy... poli } protected SearchClientBuilder getSearchClientBuilder(String indexName, boolean isSync) { - return getSearchClientBuilderHelper(indexName, true, isSync); - - } + return getSearchClientBuilderHelper(indexName, isSync); - protected SearchClientBuilder getSearchClientBuilderWithoutAssertingClient(String indexName, boolean isSync) { - return getSearchClientBuilderHelper(indexName, false, isSync); } /** * Retrieve the appropriate TokenCredential based on the test mode. * - * @param interceptorManager the interceptor manager * @return The appropriate token credential */ - public static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { + public static TokenCredential getTestTokenCredential() { return TestHelpers.getTestTokenCredential(); } - private SearchClientBuilder getSearchClientBuilderHelper(String indexName, boolean wrapWithAssertingClient, - boolean isSync) { - SearchClientBuilder builder = new SearchClientBuilder().endpoint(ENDPOINT) + private SearchClientBuilder getSearchClientBuilderHelper(String indexName, boolean isSync) { + SearchClientBuilder builder = new SearchClientBuilder().endpoint(SEARCH_ENDPOINT) .indexName(indexName) - .credential(getTestTokenCredential(interceptorManager)) - .httpClient(getHttpClient(wrapWithAssertingClient, interceptorManager, isSync)) + .credential(getTestTokenCredential()) + .httpClient(getHttpClient(interceptorManager, isSync)) .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY); // Disable `("$..token")` and `name` sanitizer @@ -228,23 +250,19 @@ private SearchClientBuilder getSearchClientBuilderHelper(String indexName, boole return builder; } - private static HttpClient getHttpClient(boolean wrapWithAssertingClient, InterceptorManager interceptorManager, - boolean isSync) { + private static HttpClient getHttpClient(InterceptorManager interceptorManager, boolean isSync) { HttpClient httpClient = interceptorManager.isPlaybackMode() ? interceptorManager.getPlaybackClient() : HttpClient.createDefault(); - if (wrapWithAssertingClient) { - if (!isSync) { - httpClient = new AssertingHttpClientBuilder(httpClient).assertAsync() - .skipRequest((ignored1, ignored2) -> false) - .build(); - } else { - httpClient = new AssertingHttpClientBuilder(httpClient).assertSync() - .skipRequest((ignored1, ignored2) -> false) - .build(); - } + if (!isSync) { + return new AssertingHttpClientBuilder(httpClient).assertAsync() + .skipRequest((ignored1, ignored2) -> false) + .build(); + } else { + return new AssertingHttpClientBuilder(httpClient).assertSync() + .skipRequest((ignored1, ignored2) -> false) + .build(); } - return httpClient; } protected SearchIndex createTestIndex(String indexName) { @@ -407,14 +425,6 @@ protected SearchIndexerDataSourceConnection createTestSqlDataSourceObject(String FAKE_DESCRIPTION, dataChangeDetectionPolicy, dataDeletionDetectionPolicy); } - protected SearchIndexerDataSourceConnection createBlobDataSource() { - // create the new data source object for this storage account and container - return SearchIndexerDataSources.createFromAzureBlobStorage( - testResourceNamer.randomName(BLOB_DATASOURCE_NAME, 32), STORAGE_CONNECTION_STRING, BLOB_CONTAINER_NAME, "/", - "real live blob", new SoftDeleteColumnDeletionDetectionPolicy().setSoftDeleteColumnName("fieldName") - .setSoftDeleteMarkerValue("someValue")); - } - protected String randomIndexName(String indexNameBase) { return testResourceNamer.randomName(indexNameBase, 64); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTests.java index 77c7cd09265d..bd961cfd7f35 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTests.java @@ -5,8 +5,8 @@ import com.azure.core.exception.HttpResponseException; import com.azure.core.models.GeoPoint; -import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.TestMode; +import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.annotation.LiveOnly; import com.azure.core.util.Context; import com.azure.search.documents.implementation.util.SearchPagedResponseAccessHelper; @@ -1142,7 +1142,7 @@ public void canUseHitHighlightingSync() { assertEquals(1, documents.size()); Map> highlights = documents.get(0).getHighlights(); - assertEquals(2, highlights.keySet().size()); + assertEquals(2, highlights.size()); assertTrue(highlights.containsKey(description)); assertTrue(highlights.containsKey(category)); @@ -1176,7 +1176,7 @@ public void canUseHitHighlightingAsync() { assertEquals(1, documents.size()); Map> highlights = documents.get(0).getHighlights(); - assertEquals(2, highlights.keySet().size()); + assertEquals(2, highlights.size()); assertTrue(highlights.containsKey(description)); assertTrue(highlights.containsKey(category)); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SuggestOptionsHandlerTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SuggestOptionsHandlerTests.java index 0be95abb858a..ef6ae0d4317a 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SuggestOptionsHandlerTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SuggestOptionsHandlerTests.java @@ -27,7 +27,7 @@ public void ensureSelectConvertsEmptyToSelectStar() { assertEquals(suggestOptions.getSelect(), emptySelect); SuggestOptions ensuredSuggestOptions = Utility.ensureSuggestOptions(suggestOptions); - assertEquals(ensuredSuggestOptions.getSelect(), SELECT_STAR); + assertEquals(SELECT_STAR, ensuredSuggestOptions.getSelect()); } @Test diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/TestHelpers.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/TestHelpers.java index b92f7f8a4cf8..d7281c32f0f7 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/TestHelpers.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/TestHelpers.java @@ -18,9 +18,9 @@ import com.azure.core.util.serializer.JsonSerializer; import com.azure.core.util.serializer.JsonSerializerProviders; import com.azure.core.util.serializer.TypeReference; +import com.azure.identity.AzureCliCredentialBuilder; import com.azure.identity.AzurePipelinesCredential; import com.azure.identity.AzurePipelinesCredentialBuilder; -import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.json.JsonProviders; import com.azure.json.JsonReader; @@ -51,7 +51,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; -import static com.azure.search.documents.SearchTestBase.ENDPOINT; +import static com.azure.search.documents.SearchTestBase.SEARCH_ENDPOINT; import static com.azure.search.documents.SearchTestBase.SERVICE_THROTTLE_SAFE_RETRY_POLICY; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -390,7 +390,7 @@ public static SearchIndexClient setupSharedIndex(String indexName, String indexD try (JsonReader jsonReader = JsonProviders.createReader(loadResource(indexDefinition))) { SearchIndex baseIndex = SearchIndex.fromJson(jsonReader); - SearchIndexClient searchIndexClient = new SearchIndexClientBuilder().endpoint(ENDPOINT) + SearchIndexClient searchIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) .credential(TestHelpers.getTestTokenCredential()) .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) @@ -419,7 +419,7 @@ public static TokenCredential getTestTokenCredential() { if (pipelineCredential != null) { return pipelineCredential; } - return new AzurePowerShellCredentialBuilder().build(); + return new AzureCliCredentialBuilder().build(); } else if (testMode == TestMode.RECORD) { return new DefaultAzureCredentialBuilder().build(); } else { @@ -478,7 +478,7 @@ public static HttpClient buildSyncAssertingClient(HttpClient httpClient) { } public static SearchIndexClient createSharedSearchIndexClient() { - return new SearchIndexClientBuilder().endpoint(ENDPOINT) + return new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .credential(getTestTokenCredential()) .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) .httpClient(buildSyncAssertingClient(HttpClient.createDefault())) diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java index ca505a36c3f7..d3c7fb993bde 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java @@ -3,52 +3,21 @@ package com.azure.search.documents; -import com.azure.core.models.GeoPoint; import com.azure.core.test.TestMode; -import com.azure.core.test.TestProxyTestBase; -import com.azure.core.util.Context; -import com.azure.search.documents.implementation.util.SearchPagedResponseAccessHelper; import com.azure.search.documents.indexes.SearchIndexAsyncClient; import com.azure.search.documents.indexes.SearchIndexClient; import com.azure.search.documents.indexes.SearchIndexClientBuilder; import com.azure.search.documents.indexes.models.BinaryQuantizationCompression; -import com.azure.search.documents.indexes.models.DistanceScoringFunction; -import com.azure.search.documents.indexes.models.DistanceScoringParameters; import com.azure.search.documents.indexes.models.HnswAlgorithmConfiguration; -import com.azure.search.documents.indexes.models.LexicalAnalyzerName; import com.azure.search.documents.indexes.models.RescoringOptions; import com.azure.search.documents.indexes.models.ScalarQuantizationCompression; -import com.azure.search.documents.indexes.models.ScoringFunctionAggregation; -import com.azure.search.documents.indexes.models.ScoringProfile; import com.azure.search.documents.indexes.models.SearchField; import com.azure.search.documents.indexes.models.SearchFieldDataType; import com.azure.search.documents.indexes.models.SearchIndex; -import com.azure.search.documents.indexes.models.SearchSuggester; -import com.azure.search.documents.indexes.models.SemanticConfiguration; -import com.azure.search.documents.indexes.models.SemanticField; -import com.azure.search.documents.indexes.models.SemanticPrioritizedFields; -import com.azure.search.documents.indexes.models.SemanticSearch; import com.azure.search.documents.indexes.models.VectorSearch; import com.azure.search.documents.indexes.models.VectorSearchCompressionRescoreStorageMethod; import com.azure.search.documents.indexes.models.VectorSearchProfile; -import com.azure.search.documents.models.QueryAnswer; -import com.azure.search.documents.models.QueryAnswerType; -import com.azure.search.documents.models.QueryCaption; -import com.azure.search.documents.models.QueryCaptionType; -import com.azure.search.documents.models.QueryType; -import com.azure.search.documents.models.SearchOptions; -import com.azure.search.documents.models.SearchResult; -import com.azure.search.documents.models.SemanticSearchOptions; -import com.azure.search.documents.models.VectorSearchOptions; -import com.azure.search.documents.models.VectorizedQuery; -import com.azure.search.documents.test.environment.models.HotelAddress; -import com.azure.search.documents.test.environment.models.HotelRoom; -import com.azure.search.documents.test.environment.models.VectorHotel; -import com.azure.search.documents.util.SearchPagedResponse; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -56,14 +25,10 @@ import reactor.test.StepVerifier; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; import static com.azure.search.documents.TestHelpers.waitForIndexing; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -74,243 +39,22 @@ @Execution(ExecutionMode.SAME_THREAD) public class VectorSearchTests extends SearchTestBase { - private static void assertKeysEqual(List results, Function keyAccessor, - String[] expectedKeys) { - assertArrayEquals(expectedKeys, results.stream().map(keyAccessor).toArray()); - } - - private static final String HOTEL_INDEX_NAME = "azsearch-vector-shared-hotel-instance"; - private static SearchIndexClient searchIndexClient; - - @BeforeAll - public static void setupClass() { - TestProxyTestBase.setupClass(); - - if (TEST_MODE == TestMode.PLAYBACK) { - return; - } - - searchIndexClient = new SearchIndexClientBuilder().endpoint(ENDPOINT) - .credential(TestHelpers.getTestTokenCredential()) - .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) - .buildClient(); - - searchIndexClient.createIndex(getVectorIndex()); - - searchIndexClient.getSearchClient(HOTEL_INDEX_NAME).uploadDocuments(VECTORIZED_HOTELS); - - waitForIndexing(); - } - - @AfterAll - protected static void cleanupClass() { - if (TEST_MODE != TestMode.PLAYBACK) { - searchIndexClient.deleteIndex(HOTEL_INDEX_NAME); - - try { - Thread.sleep(5000); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - } - } - private final List indexesToDelete = new ArrayList<>(); @AfterEach public void deleteIndexes() { if (TEST_MODE != TestMode.PLAYBACK) { + SearchIndexClient searchIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) + .credential(TestHelpers.getTestTokenCredential()) + .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) + .buildClient(); + for (String index : indexesToDelete) { searchIndexClient.deleteIndex(index); } } } - @Test - public void singleVectorSearchAsync() { - SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); - waitForIndexing(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName"); - - StepVerifier.create(searchClient.search(null, searchOptions).collectList()) - .assertNext(results -> assertKeysEqual(results, - r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), new String[] { "3", "5", "1" })) - .verifyComplete(); - } - - @Test - public void singleVectorSearchSync() { - SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); - waitForIndexing(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName"); - - List results - = searchClient.search(null, searchOptions, Context.NONE).stream().collect(Collectors.toList()); - - assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), - new String[] { "3", "5", "1" }); - } - - @Test - public void singleVectorSearchWithFilterAsync() { - SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); - waitForIndexing(); - SearchOptions searchOptions = new SearchOptions() - .setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName", "Category") - .setFilter("Category eq 'Budget'"); - - StepVerifier.create(searchClient.search(null, searchOptions).collectList()) - .assertNext(results -> assertKeysEqual(results, - r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), new String[] { "3", "5", "4" })) - .verifyComplete(); - } - - @Test - public void singleVectorSearchWithFilterSync() { - SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); - waitForIndexing(); - SearchOptions searchOptions = new SearchOptions() - .setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName", "Category") - .setFilter("Category eq 'Budget'"); - - List results - = searchClient.search(null, searchOptions, Context.NONE).stream().collect(Collectors.toList()); - - assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), - new String[] { "3", "5", "4" }); - } - - @Test - public void simpleHybridSearchAsync() { - SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); - waitForIndexing(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName"); - - StepVerifier.create(searchClient.search("Top hotels in town", searchOptions).collectList()) - .assertNext( - results -> assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), - new String[] { "3", "1", "5", "2", "10", "4", "9" })) - .verifyComplete(); - } - - @Test - public void simpleHybridSearchSync() { - SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); - waitForIndexing(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName"); - - List results = searchClient.search("Top hotels in town", searchOptions, Context.NONE) - .stream() - .collect(Collectors.toList()); - - assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), - new String[] { "3", "1", "5", "2", "10", "4", "9" }); - } - - @Test - @Disabled("Need to get manual recordings as this doesn't work with all SKUs or regions.") - public void semanticHybridSearchAsync() { - SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); - - SearchOptions searchOptions = new SearchOptions() - .setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName", "Description", "Category") - .setQueryType(QueryType.SEMANTIC) - .setSemanticSearchOptions(new SemanticSearchOptions().setSemanticConfigurationName("my-semantic-config") - .setQueryCaption(new QueryCaption(QueryCaptionType.EXTRACTIVE)) - .setQueryAnswer(new QueryAnswer(QueryAnswerType.EXTRACTIVE))); - - StepVerifier.create(searchClient - .search("Is there any hotel located on the main commercial artery of the city in the heart of New York?", - searchOptions) - .byPage() - .collectList()).assertNext(pages -> { - SearchPagedResponse page1 = pages.get(0); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1)); - assertEquals(1, SearchPagedResponseAccessHelper.getQueryAnswers(page1).size()); - assertEquals("9", SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getKey()); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getHighlights()); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getText()); - - List results = new ArrayList<>(); - for (SearchPagedResponse page : pages) { - for (SearchResult result : page.getValue()) { - results.add(result); - - assertNotNull(result.getSemanticSearch().getQueryCaptions()); - assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getHighlights()); - assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getText()); - } - } - - assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), - new String[] { "9", "3", "2", "5", "10", "1", "4" }); - }).verifyComplete(); - } - - @Test - @Disabled("Need to get manual recordings as this doesn't work with all SKUs or regions.") - public void semanticHybridSearchSync() { - SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); - waitForIndexing(); - SearchOptions searchOptions = new SearchOptions() - .setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) - .setFields("DescriptionVector"))) - .setSelect("HotelId", "HotelName", "Description", "Category") - .setQueryType(QueryType.SEMANTIC) - .setSemanticSearchOptions(new SemanticSearchOptions().setSemanticConfigurationName("my-semantic-config") - .setQueryCaption(new QueryCaption(QueryCaptionType.EXTRACTIVE)) - .setQueryAnswer(new QueryAnswer(QueryAnswerType.EXTRACTIVE))); - - List pages = searchClient - .search("Is there any hotel located on the main commercial artery of the city in the heart of New York?", - searchOptions, Context.NONE) - .streamByPage() - .collect(Collectors.toList()); - - SearchPagedResponse page1 = pages.get(0); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1)); - assertEquals(1, SearchPagedResponseAccessHelper.getQueryAnswers(page1).size()); - assertEquals("9", SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getKey()); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getHighlights()); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getText()); - - List results = new ArrayList<>(); - for (SearchPagedResponse page : pages) { - for (SearchResult result : page.getValue()) { - results.add(result); - - assertNotNull(result.getSemanticSearch().getQueryCaptions()); - assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getHighlights()); - assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getText()); - } - } - - assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), - new String[] { "9", "3", "2", "5", "10", "1", "4" }); - } - @SuppressWarnings("unchecked") @Test public void updateExistingIndexToAddVectorFieldsAsync() { @@ -392,8 +136,7 @@ public void updateExistingIndexToAddVectorFieldsAsync() { assertEquals(document.get("Id"), response.get("Id")); assertEquals(document.get("Name"), response.get("Name")); assertNotNull(response.get("DescriptionVector")); - compareFloatListToDeserializedFloatList(VectorSearchEmbeddings.DEFAULT_VECTORIZE_DESCRIPTION, - (List) response.get("DescriptionVector")); + compareFloatListToDeserializedFloatList((List) response.get("DescriptionVector")); }).verifyComplete(); } @@ -465,12 +208,11 @@ public void updateExistingIndexToAddVectorFieldsSync() { assertEquals(document.get("Id"), responseDocument.get("Id")); assertEquals(document.get("Name"), responseDocument.get("Name")); - compareFloatListToDeserializedFloatList(VectorSearchEmbeddings.DEFAULT_VECTORIZE_DESCRIPTION, - (List) responseDocument.get("DescriptionVector")); + compareFloatListToDeserializedFloatList((List) responseDocument.get("DescriptionVector")); } - // create a test that synchronously tests the ability to use VectorSearchCompression.truncationDimension to reduce the dimensionality of the vector - @SuppressWarnings("unchecked") + // create a test that synchronously tests the ability to use VectorSearchCompression.truncationDimension to reduce + // the dimensionality of the vector @Test public void testVectorSearchCompressionTruncationDimensionSync() { // create a new index with a vector field @@ -502,8 +244,8 @@ public void testVectorSearchCompressionTruncationDimensionSync() { } - // create a test that asynchronously tests the ability to use VectorSearchCompression.truncationDimension to reduce the dimensionality of the vector - @SuppressWarnings("unchecked") + // create a test that asynchronously tests the ability to use VectorSearchCompression.truncationDimension to reduce + // the dimensionality of the vector @Test public void testVectorSearchCompressionTruncationDimensionAsync() { // create a new index with a vector field @@ -536,8 +278,8 @@ public void testVectorSearchCompressionTruncationDimensionAsync() { }).verifyComplete(); } - // write a test that asynchronously tests the ability to upload a vector field to an index using BinaryQuantizationCompression - @SuppressWarnings("unchecked") + // write a test that asynchronously tests the ability to upload a vector field to an index using + // BinaryQuantizationCompression @Test public void testVectorSearchCompressionBinaryQuantizationAsync() { // create a new index with a vector field @@ -572,8 +314,8 @@ public void testVectorSearchCompressionBinaryQuantizationAsync() { }).verifyComplete(); } - // write a test that synchronously tests the ability to upload a vector field to an index using BinaryQuantizationCompression - @SuppressWarnings("unchecked") + // write a test that synchronously tests the ability to upload a vector field to an index using + // BinaryQuantizationCompression @Test public void testVectorSearchCompressionBinaryQuantizationSync() { // create a new index with a vector field @@ -606,30 +348,6 @@ public void testVectorSearchCompressionBinaryQuantizationSync() { assertEquals(compressionName, retrievedIndex.getVectorSearch().getCompressions().get(0).getCompressionName()); } - // a test that creates a hybrid search query with a vector search query and a regular search query, and utilizes the vector query - // fiter override to filter the vector search results - @Test - public void testHybridSearchWithVectorFilterOverride() { - // create a new index with a vector field - - // create a hybrid search query with a vector search query and a regular search query - SearchOptions searchOptions = new SearchOptions().setFilter("Rating ge 3") - .setSelect("HotelId", "HotelName", "Rating") - .setVectorSearchOptions(new VectorSearchOptions().setQueries( - new VectorizedQuery(VectorSearchEmbeddings.DEFAULT_VECTORIZE_DESCRIPTION).setFields("DescriptionVector") - .setFilterOverride("HotelId eq '1'"))); - - // run the hybrid search query - SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); - List results - = searchClient.search("fancy", searchOptions, Context.NONE).stream().collect(Collectors.toList()); - - // check that the results are as expected - assertEquals(1, results.size()); - assertEquals("1", results.get(0).getDocument(SearchDocument.class).get("HotelId")); - - } - @Test public void testVectorSearchCompressionsEnableRescoringDiscardOriginalsSync() { String indexName = randomIndexName("compressiontruncationdimension"); @@ -705,278 +423,22 @@ public void testVectorSearchCompressionsEnableRescoringDiscardOriginalsAsync() { compression.getRescoringOptions().getRescoreStorageMethod()); } - private static void compareFloatListToDeserializedFloatList(List expected, List actual) { + private static void compareFloatListToDeserializedFloatList(List actual) { if (actual == null) { - assertNull(expected); + assertNull(VectorSearchEmbeddings.DEFAULT_VECTORIZE_DESCRIPTION); return; } - assertEquals(expected.size(), actual.size()); + assertEquals(VectorSearchEmbeddings.DEFAULT_VECTORIZE_DESCRIPTION.size(), actual.size()); Object obj = actual.get(0); if (obj instanceof Float || obj instanceof Double) { - for (int i = 0; i < expected.size(); i++) { - assertEquals(expected.get(i), actual.get(i).floatValue()); + for (int i = 0; i < VectorSearchEmbeddings.DEFAULT_VECTORIZE_DESCRIPTION.size(); i++) { + assertEquals(VectorSearchEmbeddings.DEFAULT_VECTORIZE_DESCRIPTION.get(i), actual.get(i).floatValue()); } } else { throw new IllegalStateException( "Deserialization of a float list returned an unexpected type. Type was: " + obj.getClass().getName()); } } - - private static SearchIndex getVectorIndex() { - return new SearchIndex(HOTEL_INDEX_NAME) - .setFields( - new SearchField("HotelId", SearchFieldDataType.STRING).setKey(true) - .setFilterable(true) - .setSortable(true) - .setFacetable(true), - new SearchField("HotelName", SearchFieldDataType.STRING).setSearchable(true) - .setFilterable(true) - .setSortable(true), - new SearchField("Description", SearchFieldDataType.STRING).setSearchable(true) - .setAnalyzerName(LexicalAnalyzerName.EN_LUCENE), - new SearchField("Description_fr", SearchFieldDataType.STRING).setSearchable(true) - .setAnalyzerName(LexicalAnalyzerName.FR_LUCENE), - new SearchField("DescriptionVector", SearchFieldDataType.collection(SearchFieldDataType.SINGLE)) - .setSearchable(true) - .setVectorSearchDimensions(1536) - .setVectorSearchProfileName("my-vector-profile"), - new SearchField("Category", SearchFieldDataType.STRING).setSearchable(true) - .setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("Tags", SearchFieldDataType.collection(SearchFieldDataType.STRING)).setSearchable(true) - .setFilterable(true) - .setFacetable(true), - new SearchField("ParkingIncluded", SearchFieldDataType.BOOLEAN).setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("SmokingAllowed", SearchFieldDataType.BOOLEAN).setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("LastRenovationDate", SearchFieldDataType.DATE_TIME_OFFSET).setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("Rating", SearchFieldDataType.INT32).setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("Location", SearchFieldDataType.GEOGRAPHY_POINT).setFilterable(true).setSortable(true), - new SearchField("Address", SearchFieldDataType.COMPLEX).setFields( - new SearchField("StreetAddress", SearchFieldDataType.STRING).setSearchable(true), - new SearchField("City", SearchFieldDataType.STRING).setSearchable(true) - .setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("StateProvince", SearchFieldDataType.STRING).setSearchable(true) - .setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("Country", SearchFieldDataType.STRING).setSearchable(true) - .setFilterable(true) - .setFacetable(true) - .setSortable(true), - new SearchField("PostalCode", SearchFieldDataType.STRING).setSearchable(true) - .setFilterable(true) - .setFacetable(true) - .setSortable(true)), - new SearchField("Rooms", SearchFieldDataType.collection(SearchFieldDataType.COMPLEX)).setFields( - new SearchField("Description", SearchFieldDataType.STRING).setSearchable(true) - .setAnalyzerName(LexicalAnalyzerName.EN_LUCENE), - new SearchField("Description_fr", SearchFieldDataType.STRING).setSearchable(true) - .setAnalyzerName(LexicalAnalyzerName.FR_LUCENE), - new SearchField("Type", SearchFieldDataType.STRING).setSearchable(true) - .setFilterable(true) - .setFacetable(true), - new SearchField("BaseRate", SearchFieldDataType.DOUBLE).setFilterable(true).setFacetable(true), - new SearchField("BedOptions", SearchFieldDataType.STRING) - .setSearchable(true) - .setFilterable(true) - .setFacetable(true), - new SearchField("SleepsCount", SearchFieldDataType.INT32) - .setFilterable(true) - .setFacetable(true), - new SearchField("SmokingAllowed", SearchFieldDataType.BOOLEAN).setFilterable(true) - .setFacetable(true), - new SearchField("Tags", SearchFieldDataType.collection(SearchFieldDataType.STRING)) - .setSearchable(true) - .setFilterable(true) - .setFacetable(true))) - .setVectorSearch(new VectorSearch() - .setProfiles( - Collections.singletonList(new VectorSearchProfile("my-vector-profile", "my-vector-config"))) - .setAlgorithms(Collections.singletonList(new HnswAlgorithmConfiguration("my-vector-config")))) - .setSemanticSearch(new SemanticSearch() - .setConfigurations(Collections.singletonList(new SemanticConfiguration("my-semantic-config", - new SemanticPrioritizedFields().setTitleField(new SemanticField("HotelName")) - .setContentFields(Collections.singletonList(new SemanticField("Description"))) - .setKeywordsFields(Collections.singletonList(new SemanticField("Category"))))))) - .setSuggesters(new SearchSuggester("sg", Arrays.asList("Description", "HotelName"))) - .setScoringProfiles(new ScoringProfile("nearest").setFunctionAggregation(ScoringFunctionAggregation.SUM) - .setFunctions(new DistanceScoringFunction("Location", 2, new DistanceScoringParameters("myloc", 100)))); - } - - /* - * Hotels with vectorized data. - */ - private static final List VECTORIZED_HOTELS = Arrays.asList( - new VectorHotel().hotelId("1") - .description("Best hotel in town if you like luxury hotels. They have an amazing infinity pool, a spa, and " - + "a really helpful concierge. The location is perfect -- right downtown, close to all the tourist " - + "attractions. We highly recommend this hotel.") - .descriptionFr("Meilleur hôtel en ville si vous aimez les hôtels de luxe. Ils ont une magnifique piscine à " - + "débordement, un spa et un concierge très utile. L'emplacement est parfait – en plein centre, à " - + "proximité de toutes les attractions touristiques. Nous recommandons fortement cet hôtel.") - .descriptionVector(VectorSearchEmbeddings.HOTEL1_VECTORIZE_DESCRIPTION) - .hotelName("Fancy Stay") - .category("Luxury") - .tags(Arrays.asList("pool", "view", "wifi", "concierge")) - .parkingIncluded(false) - .smokingAllowed(false) - .lastRenovationDate(parseDate("2010-06-27T00:00:00Z")) - .rating(5) - .location(new GeoPoint(-122.131577, 47.678581)), - new VectorHotel().hotelId("2") - .description("Cheapest hotel in town. Infact, a motel.") - .descriptionFr("Hôtel le moins cher en ville. Infact, un motel.") - .descriptionVector(VectorSearchEmbeddings.HOTEL2_VECTORIZE_DESCRIPTION) - .hotelName("Roach Motel") - .category("Budget") - .tags(Arrays.asList("motel", "budget")) - .parkingIncluded(true) - .smokingAllowed(true) - .lastRenovationDate(parseDate("1982-04-28T00:00:00Z")) - .rating(1) - .location(new GeoPoint(-122.131577, 49.678581)), - new VectorHotel().hotelId("3") - .description("Very popular hotel in town") - .descriptionFr("Hôtel le plus populaire en ville") - .descriptionVector(VectorSearchEmbeddings.HOTEL3_VECTORIZE_DESCRIPTION) - .hotelName("EconoStay") - .category("Budget") - .tags(Arrays.asList("wifi", "budget")) - .parkingIncluded(true) - .smokingAllowed(false) - .lastRenovationDate(parseDate("1995-07-01T00:00:00Z")) - .rating(4) - .location(new GeoPoint(-122.131577, 46.678581)), - new VectorHotel().hotelId("4") - .description("Pretty good hotel") - .descriptionFr("Assez bon hôtel") - .descriptionVector(VectorSearchEmbeddings.HOTEL4_VECTORIZE_DESCRIPTION) - .hotelName("Express Rooms") - .category("Budget") - .tags(Arrays.asList("wifi", "budget")) - .parkingIncluded(true) - .smokingAllowed(false) - .lastRenovationDate(parseDate("1995-07-01T00:00:00Z")) - .rating(4) - .location(new GeoPoint(-122.131577, 48.678581)), - new VectorHotel().hotelId("5") - .description("Another good hotel") - .descriptionFr("Un autre bon hôtel") - .descriptionVector(VectorSearchEmbeddings.HOTEL5_VECTORIZE_DESCRIPTION) - .hotelName("Comfy Place") - .category("Budget") - .tags(Arrays.asList("wifi", "budget")) - .parkingIncluded(true) - .smokingAllowed(false) - .lastRenovationDate(parseDate("2012-08-12T00:00:00Z")) - .rating(4) - .location(new GeoPoint(-122.131577, 48.678581)) - .address(new HotelAddress().streetAddress("677 5th Ave") - .city("NEW YORK") - .stateProvince("NY") - .country("USA") - .postalCode("10022")), - new VectorHotel().hotelId("6") - .description("Surprisingly expensive. Model suites have an ocean-view.") - .descriptionVector(VectorSearchEmbeddings.HOTEL6_VECTORIZE_DESCRIPTION) - .lastRenovationDate(null), - new VectorHotel().hotelId("7") - .description("Modern architecture, very polite staff and very clean. Also very affordable.") - .descriptionFr("Architecture moderne, personnel poli et très propre. Aussi très abordable.") - .descriptionVector(VectorSearchEmbeddings.HOTEL7_VECTORIZE_DESCRIPTION) - .hotelName("Modern Stay"), - new VectorHotel().hotelId("8") - .description("Has some road noise and is next to the very police station. Bathrooms had morel coverings.") - .descriptionFr("Il y a du bruit de la route et se trouve à côté de la station de police. Les salles de " - + "bain avaient des revêtements de morilles.") - .descriptionVector(VectorSearchEmbeddings.HOTEL8_VECTORIZE_DESCRIPTION), - new VectorHotel().hotelId("9") - .hotelName("Secret Point Motel") - .description("The hotel is ideally located on the main commercial artery of the city in the heart of " - + "New York. A few minutes away is Time's Square and the historic centre of the city, as well as other " - + "places of interest that make New York one of America's most attractive and cosmopolitan cities.") - .descriptionFr("L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein " - + "cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la " - + "ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus " - + "attractives et cosmopolites de l'Amérique.") - .descriptionVector(VectorSearchEmbeddings.HOTEL9_VECTORIZE_DESCRIPTION) - .category("Boutique") - .tags(Arrays.asList("pool", "air conditioning", "concierge")) - .parkingIncluded(false) - .smokingAllowed(true) - .lastRenovationDate(parseDate("1970-01-18T00:00:00Z")) - .rating(4) - .location(new GeoPoint(-73.97332, 40.763843)) - .address(new HotelAddress().streetAddress("677 5th Ave") - .city("New York") - .stateProvince("NY") - .country("USA") - .postalCode("10022")) - .rooms(Arrays.asList( - new HotelRoom().description("Budget Room, 1 Queen Bed (Cityside)") - .descriptionFr("Chambre Économique, 1 grand lit (côté ville)") - .type("Budget Room") - .baseRate(9.69) - .bedOptions("1 Queen Bed") - .sleepsCount(2) - .smokingAllowed(true) - .tags(new String[] { "vcr/dvd" }), - new HotelRoom().description("Budget Room, 1 King Bed (Mountain View)") - .descriptionFr("Chambre Économique, 1 très grand lit (Mountain View)") - .type("Budget Room") - .baseRate(8.09) - .bedOptions("1 King Bed") - .sleepsCount(2) - .smokingAllowed(true) - .tags(new String[] { "vcr/dvd", "jacuzzi tub" }))), - new VectorHotel().hotelId("10") - .hotelName("Countryside Hotel") - .description("Save up to 50% off traditional hotels. Free WiFi, great location near downtown, full " - + "kitchen, washer & dryer, 24/7 support, bowling alley, fitness center and more.") - .descriptionFr("Économisez jusqu'à 50% sur les hôtels traditionnels. WiFi gratuit, très bien situé près " - + "du centre-ville, cuisine complète, laveuse & sécheuse, support 24/7, bowling, centre de fitness et " - + "plus encore.") - .descriptionVector(VectorSearchEmbeddings.HOTEL10_VECTORIZE_DESCRIPTION) - .category("Budget") - .tags(Arrays.asList("24-hour front desk service", "coffee in lobby", "restaurant")) - .parkingIncluded(false) - .smokingAllowed(true) - .lastRenovationDate(parseDate("1999-09-06T00:00:00Z")) - .rating(3) - .location(new GeoPoint(-78.940483, 35.904160)) - .address(new HotelAddress().streetAddress("6910 Fayetteville Rd") - .city("Durham") - .stateProvince("NC") - .country("USA") - .postalCode("27713")) - .rooms(Arrays.asList( - new HotelRoom().description("Suite, 1 King Bed (Amenities)") - .descriptionFr("Suite, 1 très grand lit (Services)") - .type("Suite") - .baseRate(2.44) - .bedOptions("1 King Bed") - .sleepsCount(2) - .smokingAllowed(true) - .tags(new String[] { "coffee maker" }), - new HotelRoom().description("Budget Room, 1 Queen Bed (Amenities)") - .descriptionFr("Chambre Économique, 1 grand lit (Services)") - .type("Budget Room") - .baseRate(7.69) - .bedOptions("1 Queen Bed") - .sleepsCount(2) - .smokingAllowed(false) - .tags(new String[] { "coffee maker" })))); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java new file mode 100644 index 000000000000..26b721c1f4ef --- /dev/null +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java @@ -0,0 +1,636 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.search.documents; + +import com.azure.core.models.GeoPoint; +import com.azure.core.test.TestMode; +import com.azure.core.test.TestProxyTestBase; +import com.azure.core.util.Context; +import com.azure.search.documents.implementation.util.SearchPagedResponseAccessHelper; +import com.azure.search.documents.indexes.SearchIndexClient; +import com.azure.search.documents.indexes.SearchIndexClientBuilder; +import com.azure.search.documents.indexes.models.DistanceScoringFunction; +import com.azure.search.documents.indexes.models.DistanceScoringParameters; +import com.azure.search.documents.indexes.models.HnswAlgorithmConfiguration; +import com.azure.search.documents.indexes.models.LexicalAnalyzerName; +import com.azure.search.documents.indexes.models.ScoringFunctionAggregation; +import com.azure.search.documents.indexes.models.ScoringProfile; +import com.azure.search.documents.indexes.models.SearchField; +import com.azure.search.documents.indexes.models.SearchFieldDataType; +import com.azure.search.documents.indexes.models.SearchIndex; +import com.azure.search.documents.indexes.models.SearchSuggester; +import com.azure.search.documents.indexes.models.SemanticConfiguration; +import com.azure.search.documents.indexes.models.SemanticField; +import com.azure.search.documents.indexes.models.SemanticPrioritizedFields; +import com.azure.search.documents.indexes.models.SemanticSearch; +import com.azure.search.documents.indexes.models.VectorSearch; +import com.azure.search.documents.indexes.models.VectorSearchProfile; +import com.azure.search.documents.models.QueryAnswer; +import com.azure.search.documents.models.QueryAnswerType; +import com.azure.search.documents.models.QueryCaption; +import com.azure.search.documents.models.QueryCaptionType; +import com.azure.search.documents.models.QueryType; +import com.azure.search.documents.models.SearchOptions; +import com.azure.search.documents.models.SearchResult; +import com.azure.search.documents.models.SemanticSearchOptions; +import com.azure.search.documents.models.VectorFilterMode; +import com.azure.search.documents.models.VectorQuery; +import com.azure.search.documents.models.VectorSearchOptions; +import com.azure.search.documents.models.VectorizedQuery; +import com.azure.search.documents.test.environment.models.HotelAddress; +import com.azure.search.documents.test.environment.models.HotelRoom; +import com.azure.search.documents.test.environment.models.VectorHotel; +import com.azure.search.documents.util.SearchPagedResponse; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static com.azure.search.documents.TestHelpers.waitForIndexing; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests vector search capabilities using a shared index created before testing begins. + */ +public class VectorSearchWithSharedIndexTests extends SearchTestBase { + private static final String HOTEL_INDEX_NAME = "azsearch-vector-shared-hotel-instance"; + private static SearchIndexClient searchIndexClient; + + @BeforeAll + public static void setupClass() { + TestProxyTestBase.setupClass(); + + if (TEST_MODE == TestMode.PLAYBACK) { + return; + } + + searchIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) + .credential(TestHelpers.getTestTokenCredential()) + .retryPolicy(SERVICE_THROTTLE_SAFE_RETRY_POLICY) + .buildClient(); + + searchIndexClient.createIndex(getVectorIndex()); + + searchIndexClient.getSearchClient(HOTEL_INDEX_NAME).uploadDocuments(VECTORIZED_HOTELS); + + waitForIndexing(); + } + + @AfterAll + protected static void cleanupClass() { + if (TEST_MODE != TestMode.PLAYBACK) { + searchIndexClient.deleteIndex(HOTEL_INDEX_NAME); + + try { + Thread.sleep(5000); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + } + } + + @Test + public void singleVectorSearchAsync() { + SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName"); + + StepVerifier.create(searchClient.search(null, searchOptions).collectList()) + .assertNext(results -> assertKeysEqual(results, + r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "1")) + .verifyComplete(); + } + + @Test + public void singleVectorSearchSync() { + SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName"); + + List results + = searchClient.search(null, searchOptions, Context.NONE).stream().collect(Collectors.toList()); + + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "1"); + } + + @Test + public void singleVectorSearchWithFilterAsync() { + SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName", "Category") + .setFilter("Category eq 'Budget'"); + + StepVerifier.create(searchClient.search(null, searchOptions).collectList()) + .assertNext(results -> assertKeysEqual(results, + r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "4")) + .verifyComplete(); + } + + @Test + public void singleVectorSearchWithFilterSync() { + SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName", "Category") + .setFilter("Category eq 'Budget'"); + + List results + = searchClient.search(null, searchOptions, Context.NONE).stream().collect(Collectors.toList()); + + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "4"); + } + + @Test + public void simpleHybridSearchAsync() { + SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName"); + + StepVerifier.create(searchClient.search("Top hotels in town", searchOptions).collectList()) + .assertNext( + results -> assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), + "3", "1", "5", "2", "10", "4", "9")) + .verifyComplete(); + } + + @Test + public void simpleHybridSearchSync() { + SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName"); + + List results = searchClient.search("Top hotels in town", searchOptions, Context.NONE) + .stream() + .collect(Collectors.toList()); + + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "1", "5", "2", + "10", "4", "9"); + } + + @Test + public void semanticHybridSearchAsync() { + SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName", "Description", "Category") + .setQueryType(QueryType.SEMANTIC) + .setSemanticSearchOptions(new SemanticSearchOptions().setSemanticConfigurationName("my-semantic-config") + .setQueryCaption(new QueryCaption(QueryCaptionType.EXTRACTIVE)) + .setQueryAnswer(new QueryAnswer(QueryAnswerType.EXTRACTIVE))); + + StepVerifier.create(searchClient + .search("Is there any hotel located on the main commercial artery of the city in the heart of New York?", + searchOptions) + .byPage() + .collectList()).assertNext(pages -> { + SearchPagedResponse page1 = pages.get(0); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1)); + assertEquals(1, SearchPagedResponseAccessHelper.getQueryAnswers(page1).size()); + assertEquals("9", SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getKey()); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getHighlights()); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getText()); + + List results = new ArrayList<>(); + for (SearchPagedResponse page : pages) { + for (SearchResult result : page.getValue()) { + results.add(result); + + assertNotNull(result.getSemanticSearch().getQueryCaptions()); + assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getHighlights()); + assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getText()); + } + } + + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "9", "3", "2", + "5", "10", "1", "4"); + }).verifyComplete(); + } + + @Test + public void semanticHybridSearchSync() { + SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); + + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery())) + .setSelect("HotelId", "HotelName", "Description", "Category") + .setQueryType(QueryType.SEMANTIC) + .setSemanticSearchOptions(new SemanticSearchOptions().setSemanticConfigurationName("my-semantic-config") + .setQueryCaption(new QueryCaption(QueryCaptionType.EXTRACTIVE)) + .setQueryAnswer(new QueryAnswer(QueryAnswerType.EXTRACTIVE))); + + List pages = searchClient + .search("Is there any hotel located on the main commercial artery of the city in the heart of New York?", + searchOptions, Context.NONE) + .streamByPage() + .collect(Collectors.toList()); + + SearchPagedResponse page1 = pages.get(0); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1)); + assertEquals(1, SearchPagedResponseAccessHelper.getQueryAnswers(page1).size()); + assertEquals("9", SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getKey()); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getHighlights()); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getText()); + + List results = new ArrayList<>(); + for (SearchPagedResponse page : pages) { + for (SearchResult result : page.getValue()) { + results.add(result); + + assertNotNull(result.getSemanticSearch().getQueryCaptions()); + assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getHighlights()); + assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getText()); + } + } + + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "9", "3", "2", "5", + "10", "1", "4"); + } + + // a test that creates a hybrid search query with a vector search query and a regular search query, and utilizes the + // vector query filter override to filter the vector search results + @Test + public void hybridSearchWithVectorFilterOverrideSync() { + // create a new index with a vector field + // create a hybrid search query with a vector search query and a regular search query + SearchOptions searchOptions = new SearchOptions().setFilter("Rating ge 3") + .setSelect("HotelId", "HotelName", "Rating") + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery() + .setFilterOverride("HotelId eq '1'"))); + + // run the hybrid search query + SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); + List results + = searchClient.search("fancy", searchOptions, Context.NONE).stream().collect(Collectors.toList()); + + // check that the results are as expected + assertEquals(1, results.size()); + assertEquals("1", results.get(0).getDocument(SearchDocument.class).get("HotelId")); + } + + @Test + public void hybridSearchWithVectorFilterOverrideAsync() { + // create a new index with a vector field + // create a hybrid search query with a vector search query and a regular search query + SearchOptions searchOptions = new SearchOptions().setFilter("Rating ge 3") + .setSelect("HotelId", "HotelName", "Rating") + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery() + .setFilterOverride("HotelId eq '1'"))); + + // run the hybrid search query + SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); + StepVerifier.create(searchClient.search("fancy", searchOptions).collectList()) + .assertNext(results -> { + // check that the results are as expected + assertEquals(1, results.size()); + assertEquals("1", results.get(0).getDocument(SearchDocument.class).get("HotelId")); + }) + .verifyComplete(); + } + + @Test + public void vectorSearchWithPostFilterModeSync() { + SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); + + SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() + .setQueries(createDescriptionVectorQuery()) + .setFilterMode(VectorFilterMode.POST_FILTER)) + .setSelect("HotelId", "HotelName"); + + List results + = searchClient.search(null, searchOptions, Context.NONE).stream().collect(Collectors.toList()); + + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "1"); + } + + @Test + public void vectorSearchWithPostFilterModeAsync() { + SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); + + SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() + .setQueries(createDescriptionVectorQuery()) + .setFilterMode(VectorFilterMode.POST_FILTER)) + .setSelect("HotelId", "HotelName"); + + StepVerifier.create(searchClient.search(null, searchOptions).collectList()) + .assertNext(results -> assertKeysEqual(results, + r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "1")) + .verifyComplete(); + } + + @Test + public void vectorSearchWithStrictPostFilterModeSync() { + SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); + + SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() + .setQueries(createDescriptionVectorQuery()) + .setFilterMode(VectorFilterMode.STRICT_POST_FILTER)) + .setSelect("HotelId", "HotelName"); + + List results + = searchClient.search(null, searchOptions, Context.NONE).stream().collect(Collectors.toList()); + + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "1"); + } + + @Test + public void vectorSearchWithStrictPostFilterModeAsync() { + SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); + + SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() + .setQueries(createDescriptionVectorQuery()) + .setFilterMode(VectorFilterMode.STRICT_POST_FILTER)) + .setSelect("HotelId", "HotelName"); + + StepVerifier.create(searchClient.search(null, searchOptions).collectList()) + .assertNext(results -> assertKeysEqual(results, + r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "5", "1")) + .verifyComplete(); + } + + private static VectorQuery createDescriptionVectorQuery() { + return new VectorizedQuery(VectorSearchEmbeddings.SEARCH_VECTORIZE_DESCRIPTION).setKNearestNeighborsCount(3) + .setFields("DescriptionVector"); + } + + private static void assertKeysEqual(List results, Function keyAccessor, + String... expectedKeys) { + assertArrayEquals(expectedKeys, results.stream().map(keyAccessor).toArray()); + } + + private static SearchIndex getVectorIndex() { + return new SearchIndex(HOTEL_INDEX_NAME) + .setFields( + new SearchField("HotelId", SearchFieldDataType.STRING).setKey(true) + .setFilterable(true) + .setSortable(true) + .setFacetable(true), + new SearchField("HotelName", SearchFieldDataType.STRING).setSearchable(true) + .setFilterable(true) + .setSortable(true), + new SearchField("Description", SearchFieldDataType.STRING).setSearchable(true) + .setAnalyzerName(LexicalAnalyzerName.EN_LUCENE), + new SearchField("Description_fr", SearchFieldDataType.STRING).setSearchable(true) + .setAnalyzerName(LexicalAnalyzerName.FR_LUCENE), + new SearchField("DescriptionVector", SearchFieldDataType.collection(SearchFieldDataType.SINGLE)) + .setSearchable(true) + .setVectorSearchDimensions(1536) + .setVectorSearchProfileName("my-vector-profile"), + new SearchField("Category", SearchFieldDataType.STRING).setSearchable(true) + .setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("Tags", SearchFieldDataType.collection(SearchFieldDataType.STRING)).setSearchable(true) + .setFilterable(true) + .setFacetable(true), + new SearchField("ParkingIncluded", SearchFieldDataType.BOOLEAN).setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("SmokingAllowed", SearchFieldDataType.BOOLEAN).setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("LastRenovationDate", SearchFieldDataType.DATE_TIME_OFFSET).setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("Rating", SearchFieldDataType.INT32).setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("Location", SearchFieldDataType.GEOGRAPHY_POINT).setFilterable(true).setSortable(true), + new SearchField("Address", SearchFieldDataType.COMPLEX).setFields( + new SearchField("StreetAddress", SearchFieldDataType.STRING).setSearchable(true), + new SearchField("City", SearchFieldDataType.STRING).setSearchable(true) + .setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("StateProvince", SearchFieldDataType.STRING).setSearchable(true) + .setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("Country", SearchFieldDataType.STRING).setSearchable(true) + .setFilterable(true) + .setFacetable(true) + .setSortable(true), + new SearchField("PostalCode", SearchFieldDataType.STRING).setSearchable(true) + .setFilterable(true) + .setFacetable(true) + .setSortable(true)), + new SearchField("Rooms", SearchFieldDataType.collection(SearchFieldDataType.COMPLEX)).setFields( + new SearchField("Description", SearchFieldDataType.STRING).setSearchable(true) + .setAnalyzerName(LexicalAnalyzerName.EN_LUCENE), + new SearchField("Description_fr", SearchFieldDataType.STRING).setSearchable(true) + .setAnalyzerName(LexicalAnalyzerName.FR_LUCENE), + new SearchField("Type", SearchFieldDataType.STRING).setSearchable(true) + .setFilterable(true) + .setFacetable(true), + new SearchField("BaseRate", SearchFieldDataType.DOUBLE).setFilterable(true).setFacetable(true), + new SearchField("BedOptions", SearchFieldDataType.STRING) + .setSearchable(true) + .setFilterable(true) + .setFacetable(true), + new SearchField("SleepsCount", SearchFieldDataType.INT32) + .setFilterable(true) + .setFacetable(true), + new SearchField("SmokingAllowed", SearchFieldDataType.BOOLEAN).setFilterable(true) + .setFacetable(true), + new SearchField("Tags", SearchFieldDataType.collection(SearchFieldDataType.STRING)) + .setSearchable(true) + .setFilterable(true) + .setFacetable(true))) + .setVectorSearch(new VectorSearch() + .setProfiles( + Collections.singletonList(new VectorSearchProfile("my-vector-profile", "my-vector-config"))) + .setAlgorithms(Collections.singletonList(new HnswAlgorithmConfiguration("my-vector-config")))) + .setSemanticSearch(new SemanticSearch() + .setConfigurations(Collections.singletonList(new SemanticConfiguration("my-semantic-config", + new SemanticPrioritizedFields().setTitleField(new SemanticField("HotelName")) + .setContentFields(Collections.singletonList(new SemanticField("Description"))) + .setKeywordsFields(Collections.singletonList(new SemanticField("Category"))))))) + .setSuggesters(new SearchSuggester("sg", Arrays.asList("Description", "HotelName"))) + .setScoringProfiles(new ScoringProfile("nearest").setFunctionAggregation(ScoringFunctionAggregation.SUM) + .setFunctions(new DistanceScoringFunction("Location", 2, new DistanceScoringParameters("myloc", 100)))); + } + + /* + * Hotels with vectorized data. + */ + private static final List VECTORIZED_HOTELS = Arrays.asList( + new VectorHotel().hotelId("1") + .description("Best hotel in town if you like luxury hotels. They have an amazing infinity pool, a spa, and " + + "a really helpful concierge. The location is perfect -- right downtown, close to all the tourist " + + "attractions. We highly recommend this hotel.") + .descriptionFr("Meilleur hôtel en ville si vous aimez les hôtels de luxe. Ils ont une magnifique piscine à " + + "débordement, un spa et un concierge très utile. L'emplacement est parfait – en plein centre, à " + + "proximité de toutes les attractions touristiques. Nous recommandons fortement cet hôtel.") + .descriptionVector(VectorSearchEmbeddings.HOTEL1_VECTORIZE_DESCRIPTION) + .hotelName("Fancy Stay") + .category("Luxury") + .tags(Arrays.asList("pool", "view", "wifi", "concierge")) + .parkingIncluded(false) + .smokingAllowed(false) + .lastRenovationDate(parseDate("2010-06-27T00:00:00Z")) + .rating(5) + .location(new GeoPoint(-122.131577, 47.678581)), + new VectorHotel().hotelId("2") + .description("Cheapest hotel in town. Infact, a motel.") + .descriptionFr("Hôtel le moins cher en ville. Infact, un motel.") + .descriptionVector(VectorSearchEmbeddings.HOTEL2_VECTORIZE_DESCRIPTION) + .hotelName("Roach Motel") + .category("Budget") + .tags(Arrays.asList("motel", "budget")) + .parkingIncluded(true) + .smokingAllowed(true) + .lastRenovationDate(parseDate("1982-04-28T00:00:00Z")) + .rating(1) + .location(new GeoPoint(-122.131577, 49.678581)), + new VectorHotel().hotelId("3") + .description("Very popular hotel in town") + .descriptionFr("Hôtel le plus populaire en ville") + .descriptionVector(VectorSearchEmbeddings.HOTEL3_VECTORIZE_DESCRIPTION) + .hotelName("EconoStay") + .category("Budget") + .tags(Arrays.asList("wifi", "budget")) + .parkingIncluded(true) + .smokingAllowed(false) + .lastRenovationDate(parseDate("1995-07-01T00:00:00Z")) + .rating(4) + .location(new GeoPoint(-122.131577, 46.678581)), + new VectorHotel().hotelId("4") + .description("Pretty good hotel") + .descriptionFr("Assez bon hôtel") + .descriptionVector(VectorSearchEmbeddings.HOTEL4_VECTORIZE_DESCRIPTION) + .hotelName("Express Rooms") + .category("Budget") + .tags(Arrays.asList("wifi", "budget")) + .parkingIncluded(true) + .smokingAllowed(false) + .lastRenovationDate(parseDate("1995-07-01T00:00:00Z")) + .rating(4) + .location(new GeoPoint(-122.131577, 48.678581)), + new VectorHotel().hotelId("5") + .description("Another good hotel") + .descriptionFr("Un autre bon hôtel") + .descriptionVector(VectorSearchEmbeddings.HOTEL5_VECTORIZE_DESCRIPTION) + .hotelName("Comfy Place") + .category("Budget") + .tags(Arrays.asList("wifi", "budget")) + .parkingIncluded(true) + .smokingAllowed(false) + .lastRenovationDate(parseDate("2012-08-12T00:00:00Z")) + .rating(4) + .location(new GeoPoint(-122.131577, 48.678581)) + .address(new HotelAddress().streetAddress("677 5th Ave") + .city("NEW YORK") + .stateProvince("NY") + .country("USA") + .postalCode("10022")), + new VectorHotel().hotelId("6") + .description("Surprisingly expensive. Model suites have an ocean-view.") + .descriptionVector(VectorSearchEmbeddings.HOTEL6_VECTORIZE_DESCRIPTION) + .lastRenovationDate(null), + new VectorHotel().hotelId("7") + .description("Modern architecture, very polite staff and very clean. Also very affordable.") + .descriptionFr("Architecture moderne, personnel poli et très propre. Aussi très abordable.") + .descriptionVector(VectorSearchEmbeddings.HOTEL7_VECTORIZE_DESCRIPTION) + .hotelName("Modern Stay"), + new VectorHotel().hotelId("8") + .description("Has some road noise and is next to the very police station. Bathrooms had morel coverings.") + .descriptionFr("Il y a du bruit de la route et se trouve à côté de la station de police. Les salles de " + + "bain avaient des revêtements de morilles.") + .descriptionVector(VectorSearchEmbeddings.HOTEL8_VECTORIZE_DESCRIPTION), + new VectorHotel().hotelId("9") + .hotelName("Secret Point Motel") + .description("The hotel is ideally located on the main commercial artery of the city in the heart of " + + "New York. A few minutes away is Time's Square and the historic centre of the city, as well as other " + + "places of interest that make New York one of America's most attractive and cosmopolitan cities.") + .descriptionFr("L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein " + + "cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la " + + "ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus " + + "attractives et cosmopolites de l'Amérique.") + .descriptionVector(VectorSearchEmbeddings.HOTEL9_VECTORIZE_DESCRIPTION) + .category("Boutique") + .tags(Arrays.asList("pool", "air conditioning", "concierge")) + .parkingIncluded(false) + .smokingAllowed(true) + .lastRenovationDate(parseDate("1970-01-18T00:00:00Z")) + .rating(4) + .location(new GeoPoint(-73.97332, 40.763843)) + .address(new HotelAddress().streetAddress("677 5th Ave") + .city("New York") + .stateProvince("NY") + .country("USA") + .postalCode("10022")) + .rooms(Arrays.asList( + new HotelRoom().description("Budget Room, 1 Queen Bed (Cityside)") + .descriptionFr("Chambre Économique, 1 grand lit (côté ville)") + .type("Budget Room") + .baseRate(9.69) + .bedOptions("1 Queen Bed") + .sleepsCount(2) + .smokingAllowed(true) + .tags(new String[] { "vcr/dvd" }), + new HotelRoom().description("Budget Room, 1 King Bed (Mountain View)") + .descriptionFr("Chambre Économique, 1 très grand lit (Mountain View)") + .type("Budget Room") + .baseRate(8.09) + .bedOptions("1 King Bed") + .sleepsCount(2) + .smokingAllowed(true) + .tags(new String[] { "vcr/dvd", "jacuzzi tub" }))), + new VectorHotel().hotelId("10") + .hotelName("Countryside Hotel") + .description("Save up to 50% off traditional hotels. Free WiFi, great location near downtown, full " + + "kitchen, washer & dryer, 24/7 support, bowling alley, fitness center and more.") + .descriptionFr("Économisez jusqu'à 50% sur les hôtels traditionnels. WiFi gratuit, très bien situé près " + + "du centre-ville, cuisine complète, laveuse & sécheuse, support 24/7, bowling, centre de fitness et " + + "plus encore.") + .descriptionVector(VectorSearchEmbeddings.HOTEL10_VECTORIZE_DESCRIPTION) + .category("Budget") + .tags(Arrays.asList("24-hour front desk service", "coffee in lobby", "restaurant")) + .parkingIncluded(false) + .smokingAllowed(true) + .lastRenovationDate(parseDate("1999-09-06T00:00:00Z")) + .rating(3) + .location(new GeoPoint(-78.940483, 35.904160)) + .address(new HotelAddress().streetAddress("6910 Fayetteville Rd") + .city("Durham") + .stateProvince("NC") + .country("USA") + .postalCode("27713")) + .rooms(Arrays.asList( + new HotelRoom().description("Suite, 1 King Bed (Amenities)") + .descriptionFr("Suite, 1 très grand lit (Services)") + .type("Suite") + .baseRate(2.44) + .bedOptions("1 King Bed") + .sleepsCount(2) + .smokingAllowed(true) + .tags(new String[] { "coffee maker" }), + new HotelRoom().description("Budget Room, 1 Queen Bed (Amenities)") + .descriptionFr("Chambre Économique, 1 grand lit (Services)") + .type("Budget Room") + .baseRate(7.69) + .bedOptions("1 Queen Bed") + .sleepsCount(2) + .smokingAllowed(false) + .tags(new String[] { "coffee maker" })))); +} diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/implementation/models/IndexActionTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/implementation/models/IndexActionTests.java index daaf16361351..eaf2dda161dc 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/implementation/models/IndexActionTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/implementation/models/IndexActionTests.java @@ -5,9 +5,7 @@ import com.azure.core.serializer.json.jackson.JacksonJsonSerializerBuilder; import com.azure.core.util.serializer.ObjectSerializer; -import com.azure.json.JsonProviders; import com.azure.json.JsonSerializable; -import com.azure.json.JsonWriter; import com.azure.search.documents.implementation.converters.IndexActionConverter; import com.azure.search.documents.models.IndexActionType; import com.fasterxml.jackson.annotation.JsonInclude; @@ -17,9 +15,7 @@ import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Map; @@ -95,11 +91,8 @@ public void nullIsExcludedInTypedSerialization() { } private static String convertToJson(JsonSerializable jsonSerializable) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - - try (JsonWriter writer = JsonProviders.createWriter(outputStream)) { - writer.writeJson(jsonSerializable).flush(); - return outputStream.toString(StandardCharsets.UTF_8.name()); + try { + return jsonSerializable.toJsonString(); } catch (IOException ex) { throw new RuntimeException(ex); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/DataSourceTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/DataSourceTests.java index d59e4e8835e5..c9e63319e126 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/DataSourceTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/DataSourceTests.java @@ -619,14 +619,14 @@ public void canUpdateConnectionData() { // Create an initial dataSource SearchIndexerDataSourceConnection initial = createTestBlobDataSource(null); - assertEquals(initial.getConnectionString(), FAKE_STORAGE_CONNECTION_STRING); + assertEquals(FAKE_STORAGE_CONNECTION_STRING, initial.getConnectionString()); // tweak the connection string and verify it was changed String newConnString = "DefaultEndpointsProtocol=https;AccountName=NotaRealYetDifferentAccount;AccountKey=AnotherFakeKey;"; initial.setConnectionString(newConnString); - assertEquals(initial.getConnectionString(), newConnString); + assertEquals(newConnString, initial.getConnectionString()); } SearchIndexerDataSourceConnection createTestBlobDataSource(DataDeletionDetectionPolicy deletionDetectionPolicy) { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java index 628d9d38cc45..4aa96e07b705 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java @@ -79,7 +79,7 @@ public static void setupSharedResources() { return; } - sharedIndexClient = new SearchIndexClientBuilder().endpoint(ENDPOINT) + sharedIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .credential(TestHelpers.getTestTokenCredential()) .buildClient(); @@ -842,7 +842,7 @@ public void canCreateAndGetIndexStatsSummarySync() { List indexNames = new ArrayList<>(); PagedIterable statsSummary = client.getIndexStatsSummary(); - assert (statsSummary.stream().count() == 0); + assert (!statsSummary.stream().findAny().isPresent()); SearchIndex index = createTestIndex(null); indexNames.add(index.getName()); @@ -860,7 +860,7 @@ public void canCreateAndGetIndexStatsSummarySync() { } statsSummary = client.getIndexStatsSummary(); - assertEquals(statsSummary.stream().count(), 5); + assertEquals(5, statsSummary.stream().count()); List returnedNames = statsSummary.stream().map(IndexStatisticsSummary::getName).collect(Collectors.toList()); for (String name : indexNames) { @@ -890,7 +890,7 @@ public void canCreateAndGetIndexStatsSummaryAsync() { indexesToDelete.add(index.getName()); } - List returnedNames = new ArrayList(); + List returnedNames = new ArrayList<>(); PagedFlux statsSummary = asyncClient.getIndexStatsSummary(); StepVerifier.create(statsSummary) diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java index 161522c4706c..a3ab56d30688 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java @@ -22,7 +22,9 @@ import com.azure.search.documents.indexes.models.SearchFieldDataType; import com.azure.search.documents.indexes.models.SearchIndex; import com.azure.search.documents.indexes.models.SearchIndexer; +import com.azure.search.documents.indexes.models.SearchIndexerDataContainer; import com.azure.search.documents.indexes.models.SearchIndexerDataSourceConnection; +import com.azure.search.documents.indexes.models.SearchIndexerDataSourceType; import com.azure.search.documents.indexes.models.SearchIndexerLimits; import com.azure.search.documents.indexes.models.SearchIndexerSkill; import com.azure.search.documents.indexes.models.SearchIndexerSkillset; @@ -30,7 +32,6 @@ import com.azure.search.documents.indexes.models.SoftDeleteColumnDeletionDetectionPolicy; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -62,7 +63,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -@Disabled public class IndexersManagementTests extends SearchTestBase { private static final String TARGET_INDEX_NAME = "indexforindexers"; private static final HttpPipelinePolicy MOCK_STATUS_PIPELINE_POLICY = (context, next) -> { @@ -130,10 +130,10 @@ public static void setupSharedResources() { return; } - sharedIndexerClient = new SearchIndexerClientBuilder().endpoint(ENDPOINT) + sharedIndexerClient = new SearchIndexerClientBuilder().endpoint(SEARCH_ENDPOINT) .credential(TestHelpers.getTestTokenCredential()) .buildClient(); - sharedIndexClient = new SearchIndexClientBuilder().endpoint(ENDPOINT) + sharedIndexClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .credential(TestHelpers.getTestTokenCredential()) .buildClient(); @@ -1154,10 +1154,16 @@ private static SearchIndexerSkillset createSkillsetObject() { private static SearchIndexerDataSourceConnection createSharedDataSource() { // create the new data source object for this storage account and container - return SearchIndexerDataSources.createFromAzureBlobStorage("shared-" + BLOB_DATASOURCE_NAME, - STORAGE_CONNECTION_STRING, BLOB_CONTAINER_NAME, "/", "real live blob", - new SoftDeleteColumnDeletionDetectionPolicy().setSoftDeleteColumnName("fieldName") - .setSoftDeleteMarkerValue("someValue")); + return new SearchIndexerDataSourceConnection("shared-" + BLOB_DATASOURCE_NAME) + .setType(SearchIndexerDataSourceType.AZURE_BLOB) + .setDescription("real live blob") + .setConnectionString(String.format( + "ResourceId=/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s;", + SUBSCRIPTION_ID, RESOURCE_GROUP, STORAGE_ACCOUNT_NAME)) + .setContainer(new SearchIndexerDataContainer(BLOB_CONTAINER_NAME).setQuery("/")) + .setDataDeletionDetectionPolicy( + new SoftDeleteColumnDeletionDetectionPolicy().setSoftDeleteColumnName("fieldName") + .setSoftDeleteMarkerValue("someValue")); } SearchIndexer createBaseTestIndexerObject(String targetIndexName, String dataSourceName) { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SkillsetManagementTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SkillsetManagementTests.java index 541f9a9f6973..b9e38d54ba45 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SkillsetManagementTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SkillsetManagementTests.java @@ -36,7 +36,6 @@ import com.azure.search.documents.indexes.models.TextSplitMode; import com.azure.search.documents.indexes.models.VisualFeature; import com.azure.search.documents.indexes.models.WebApiSkill; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -222,7 +221,6 @@ public void createSkillsetReturnsCorrectDefinitionOcrShaperAsync() { } @Test - @Disabled("TODO: Service is not responding to api calls. 500 error thrown with little information.") public void createSkillsetReturnsCorrectDefinitionOcrSplitTextSync() { createAndValidateSkillsetSync( createTestSkillsetOcrSplitText(OcrSkillLanguage.EN, SplitSkillLanguage.EN, TextSplitMode.PAGES)); @@ -240,7 +238,6 @@ public void createSkillsetReturnsCorrectDefinitionOcrSplitTextSync() { } @Test - @Disabled("TODO: Service is not responding to api calls. 500 error thrown with little information.") public void createSkillsetReturnsCorrectDefinitionOcrSplitTextAsync() { createAndValidateSkillsetAsync( createTestSkillsetOcrSplitText(OcrSkillLanguage.EN, SplitSkillLanguage.EN, TextSplitMode.PAGES)); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SynonymMapManagementTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SynonymMapManagementTests.java index 3e7f3961b5b7..7c441b629465 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SynonymMapManagementTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SynonymMapManagementTests.java @@ -52,7 +52,7 @@ public static void beforeAll() { return; // Running in PLAYBACK, no need to cleanup. } - SearchIndexClient cleanupClient = new SearchIndexClientBuilder().endpoint(ENDPOINT) + SearchIndexClient cleanupClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .credential(TestHelpers.getTestTokenCredential()) .buildClient(); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/IndexBatchExceptionTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/IndexBatchExceptionTests.java index 8ac5fc142868..34bc75c03147 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/IndexBatchExceptionTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/IndexBatchExceptionTests.java @@ -26,7 +26,7 @@ public class IndexBatchExceptionTests { @Test public void clientShouldNotRetrySuccessfulBatch() { IndexDocumentsResult result - = new IndexDocumentsResult(Arrays.asList(createSucceededResult("1"), createResult("2"))); + = new IndexDocumentsResult(Arrays.asList(createSucceededResult(), createResult("2"))); assertRetryBatchEmpty(result); } @@ -42,7 +42,7 @@ public void clientShouldNotRetryBatchWithAllNonRetriableFailures() { @Test public void clientShouldNotRetryBatchWithSuccessesAndNonRetriableFailures() { IndexDocumentsResult result - = new IndexDocumentsResult(Arrays.asList(createSucceededResult("1"), createFailedResult("2", 500), + = new IndexDocumentsResult(Arrays.asList(createSucceededResult(), createFailedResult("2", 500), createFailedResult("3", 404), createResult("4"), createFailedResult("5", 400))); assertRetryBatchEmpty(result); @@ -59,7 +59,7 @@ public void clientShouldRetryBatchWithAllRetriableFailures() { @Test public void clientShouldRetryBatchWithSomeRetriableFailures() { IndexDocumentsResult result - = new IndexDocumentsResult(Arrays.asList(createSucceededResult("1"), createFailedResult("2", 500), + = new IndexDocumentsResult(Arrays.asList(createSucceededResult(), createFailedResult("2", 500), createFailedResult("3", 422), createFailedResult("4", 404), createFailedResult("5", 409), createFailedResult("6", 400), createResult("7"), createFailedResult("8", 503))); @@ -69,7 +69,7 @@ public void clientShouldRetryBatchWithSomeRetriableFailures() { @Test public void clientShouldNotRetryResultWithUnexpectedStatusCode() { IndexDocumentsResult result = new IndexDocumentsResult( - Arrays.asList(createSucceededResult("1"), createFailedResult("2", 502), createFailedResult("3", 503))); + Arrays.asList(createSucceededResult(), createFailedResult("2", 502), createFailedResult("3", 503))); assertRetryBatchContains(result, Collections.singletonList("3")); } @@ -122,8 +122,8 @@ private static IndexBatchBase getTypedRetryBatch(IndexDocumentsResult res return exception.findFailedActionsToRetry(originalBatch, Hotel::getHotelId); } - private static IndexingResult createSucceededResult(String key) { - return new IndexingResult(key, true, 200); + private static IndexingResult createSucceededResult() { + return new IndexingResult("1", true, 200); } private static IndexingResult createResult(String key) { diff --git a/sdk/search/test-resources.bicep b/sdk/search/test-resources.bicep index 06cdfd97daf6..573e0ad906e2 100644 --- a/sdk/search/test-resources.bicep +++ b/sdk/search/test-resources.bicep @@ -1,21 +1,24 @@ +targetScope = 'resourceGroup' + +@minLength(4) +@maxLength(20) @description('The base resource name.') param baseName string = resourceGroup().name -@description('The Search service endpoint suffix.') -param searchEndpointSuffix string = 'search.windows.net' - -@description('The Storage account endpoint suffix.') -param storageEndpointSuffix string = 'core.windows.net' - @description('The location of the resource. By default, this is the same as the resource group.') param location string = resourceGroup().location -@description('The principal to assign the role to. This is application object id.') -param testApplicationOid string +@description('The tenant ID to which the application and resources belong.') +param tenantId string = subscription().tenantId + +@description('The client OID to grant access to test resources.') +param testApplicationOid string = deployer().objectId + +@description('The Search service endpoint suffix.') +param searchEndpointSuffix string = 'search.windows.net' @description('The Search service SKU to create.') @allowed([ - 'free' 'basic' 'standard' ]) @@ -23,38 +26,73 @@ param searchSku string = 'basic' // Variables var searchServiceName = 'azs-java-${baseName}' -var storageAccountName = 'search${baseName}' -var searchIndexDataContributorRoleId = '8ebe5a00-799e-43f5-93ac-243d3dce84a7' -var searchServiceContributorRoleId = '7ca78c08-252a-4471-8644-bb5ff32d4ba0' - -// Role assignment for Search Index Data Contributor -resource searchIndexDataContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, testApplicationOid, searchIndexDataContributorRoleId) - scope: resourceGroup() +var storageAccountName = substring('search${baseName}', 0, 24) + +// Static resource group name for TME tenant +var staticResourceGroupName = 'static-test-resources' + +// Is this deployment to the TME tenant +var isTmeTenant = tenantId == '70a036f6-8e4d-4615-bad6-149c02e7720d' + +// Deployed OpenAI resource for non-TME tenants +resource openai 'Microsoft.CognitiveServices/accounts@2025-06-01' = if (!isTmeTenant) { + name: toLower(baseName) + location: location + kind: 'OpenAI' + sku: { + name: 'S0' + } properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', searchIndexDataContributorRoleId) - principalId: testApplicationOid + customSubDomainName: toLower(baseName) + publicNetworkAccess: 'Enabled' + disableLocalAuth: true + } + // Deployment of the gpt-4.1-nano model + resource openaiDeployment 'deployments' = { + name: 'search-knowledge-agent-model' + sku: { + name: 'Standard' + capacity: 250000 + } + properties: { + model: { + format: 'OpenAI' + name: 'gpt-4.1-nano' + } + } } } -// Role assignment for Search Service Contributor -resource searchServiceContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, testApplicationOid, searchServiceContributorRoleId) - scope: resourceGroup() - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', searchServiceContributorRoleId) - principalId: testApplicationOid +// Static OpenAI resource for TME tenant +resource openaiStatic 'Microsoft.CognitiveServices/accounts@2025-06-01' existing = if (isTmeTenant) { + name: 'azsdk-openai-shared-test' + scope: resourceGroup(staticResourceGroupName) + // Static model deployment + resource openaiStaticDeployment 'deployments' existing = { + name: 'search-knowledge-agent-model' } } -// Azure Search Service -resource searchService 'Microsoft.Search/searchServices@2025-05-01' = { +// Managed identity to place on the search service +resource searchServiceIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = if (!isTmeTenant) { + name: '${baseName}-search-service-identity' + location: location +} + +resource staticSearchServiceIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (isTmeTenant) { + name: 'azsdk-search-service-identity' + scope: resourceGroup(staticResourceGroupName) +} + +// Azure AI Search service +resource search 'Microsoft.Search/searchServices@2025-05-01' = { name: searchServiceName location: location sku: { name: searchSku } properties: { + disableLocalAuth: true replicaCount: 1 partitionCount: 1 hostingMode: 'default' @@ -62,13 +100,18 @@ resource searchService 'Microsoft.Search/searchServices@2025-05-01' = { networkRuleSet: { ipRules: [] } - disableLocalAuth: true authOptions: null endpoint: 'https://${searchServiceName}.${searchEndpointSuffix}' + semanticSearch: 'free' + } + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${tenantId != '70a036f6-8e4d-4615-bad6-149c02e7720d' ? searchServiceIdentity.id : staticSearchServiceIdentity.id}': {} + } } } -// Storage Account resource storageAccount 'Microsoft.Storage/storageAccounts@2025-01-01' = { name: storageAccountName location: location @@ -79,21 +122,131 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2025-01-01' = { properties: { accessTier: 'Hot' allowSharedKeyAccess: false + allowBlobPublicAccess: false supportsHttpsTrafficOnly: true minimumTlsVersion: 'TLS1_2' } + + resource blobServices 'blobServices' = { + name: 'default' + resource blobContainer 'containers' = { + name: 'searchcontainer' + properties: { + publicAccess: 'None' + } + } + } +} + +// Role assignments: +// Identity | Resource | Role +// ------------------------------------------------------------------------------- +// search service | storage account | Storage Blob Data Reader +// test application | storage account | Storage Blob Data Contributor +// test application | search service | Search Index Data Contributor +// test application | search service | Search Service Contributor +// search service | openai account | Cognitive Services OpenAI Contributor + +// Storage Blob Data Reader role definition +resource storageBlobDataReaderRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + scope: subscription() + // This is the Storage Blob Data Reader role + // See https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#storage-blob-data-reader + name: '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' +} + +// Storage Blob Data Contributor role definition +resource storageBlobDataContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + scope: subscription() + // This is the Storage Blob Contributor Reader role + // See https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#storage-blob-data-contributor + name: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' +} + +// Search Index Data Contributor role definition +resource searchIndexDataContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + scope: subscription() + // This is the Search Index Data Reader role + // See https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#search-index-data-contributor + name: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' +} + +// Search Service Contributor role definition +resource searchServiceContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + scope: subscription() + // This is the Search Service Contributor role + // See https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#search-service-contributor + name: '7ca78c08-252a-4471-8644-bb5ff32d4ba0' +} + +// Assign Storage Blob Data Reader role for Azure Search service identity on the storage account +resource search_Storage_RoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(storageBlobDataReaderRoleDefinition.id, search.id, storageAccount.id) + scope: storageAccount + properties: { + principalId: tenantId != '70a036f6-8e4d-4615-bad6-149c02e7720d' + ? searchServiceIdentity.properties.principalId + : staticSearchServiceIdentity.properties.principalId + roleDefinitionId: storageBlobDataReaderRoleDefinition.id + } +} + +// Assign Storage Blob Data Reader role for Azure Search service identity on the storage account +resource testApp_Storage_RoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(storageBlobDataContributorRoleDefinition.id, testApplicationOid, storageAccount.id) + scope: storageAccount + properties: { + principalId: testApplicationOid + roleDefinitionId: storageBlobDataContributorRoleDefinition.id + } +} + +// Assign Search Index Data Reader role to testApplicationOid +resource testApp_search_indexDataReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(searchIndexDataContributorRoleDefinition.id, testApplicationOid, search.id) + scope: search + properties: { + principalId: testApplicationOid + roleDefinitionId: searchIndexDataContributorRoleDefinition.id + } +} + +// Assign Search Service Contributor role to testApplicationOid +resource testApp_search_contributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(searchServiceContributorRoleDefinition.id, testApplicationOid, search.id) + scope: search + properties: { + principalId: testApplicationOid + roleDefinitionId: searchServiceContributorRoleDefinition.id + } } -resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2025-01-01' = { - parent: storageAccount - name: 'default' +// Cognitive Services OpenAI Contributor role definition +resource openaiContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + scope: subscription() + // Cognitive Services OpenAI Contributor role + // See https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#cognitive-services-openai-contributor + name: 'a001fd3d-188f-4b5d-821b-7da978bf7442' } -// Blob Container -resource blobContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2025-01-01' = { - parent: blobServices - name: 'searchcontainer' +// Assign Cognitive Services OpenAI Contributor role to the search resource's identity if we created the OpenAI resource +resource search_openAi_roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (!isTmeTenant) { + name: guid(openaiContributorRoleDefinition.id, searchServiceIdentity.id, openai.id) + scope: openai + properties: { + principalId: searchServiceIdentity.properties.principalId + roleDefinitionId: openaiContributorRoleDefinition.id + } } // Outputs -output SEARCH_SERVICE_ENDPOINT string = searchService.properties.endpoint +output SEARCH_SERVICE_ENDPOINT string = search.properties.endpoint +output SEARCH_STORAGE_ACCOUNT_NAME string = storageAccount.name +output SEARCH_STORAGE_CONTAINER_NAME string = storageAccount::blobServices::blobContainer.name +output SEARCH_OPENAI_ENDPOINT string = isTmeTenant ? openaiStatic.properties.endpoint : openai.properties.endpoint +output SEARCH_OPENAI_DEPLOYMENT_NAME string = isTmeTenant + ? openaiStatic::openaiStaticDeployment.name + : openai::openaiDeployment.name +output SEARCH_OPENAI_MODEL_NAME string = isTmeTenant + ? openaiStatic::openaiStaticDeployment.properties.model.name + : openai::openaiDeployment.properties.model.name From aea0b77b168c3469ead0107cd252fb34ee2fdc6f Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Fri, 29 Aug 2025 17:29:42 -0400 Subject: [PATCH 08/12] Add tests --- sdk/search/azure-search-documents/assets.json | 2 +- .../search/documents/KnowledgeAgentTests.java | 266 ++++++++++-------- .../documents/KnowledgeSourceTests.java | 85 +++--- ...SearchIndexingBufferedSenderUnitTests.java | 4 +- .../search/documents/SearchTestBase.java | 49 ++-- .../VectorSearchWithSharedIndexTests.java | 93 +++--- .../indexes/IndexersManagementTests.java | 10 +- sdk/search/test-resources.bicep | 13 +- 8 files changed, 294 insertions(+), 228 deletions(-) diff --git a/sdk/search/azure-search-documents/assets.json b/sdk/search/azure-search-documents/assets.json index bf72e32f2250..0badaf2c915d 100644 --- a/sdk/search/azure-search-documents/assets.json +++ b/sdk/search/azure-search-documents/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "java", "TagPrefix": "java/search/azure-search-documents", - "Tag": "java/search/azure-search-documents_ab303259b0" + "Tag": "java/search/azure-search-documents_3d1f64a492" } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java index 9d1895c1702e..89d4c79e2d12 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java @@ -27,6 +27,9 @@ import com.azure.search.documents.indexes.models.KnowledgeAgentOutputConfigurationModality; import com.azure.search.documents.indexes.models.KnowledgeSourceReference; import com.azure.search.documents.indexes.models.SearchIndex; +import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSource; +import com.azure.search.documents.indexes.models.SearchIndexKnowledgeSourceParameters; +import com.azure.search.documents.indexes.models.SearchIndexerDataUserAssignedIdentity; import com.azure.search.documents.indexes.models.SemanticConfiguration; import com.azure.search.documents.indexes.models.SemanticField; import com.azure.search.documents.indexes.models.SemanticPrioritizedFields; @@ -34,10 +37,14 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import reactor.util.function.Tuple2; +import reactor.util.function.Tuples; import java.io.IOException; import java.io.UncheckedIOException; @@ -63,10 +70,10 @@ public class KnowledgeAgentTests extends SearchTestBase { private static final String HOTEL_INDEX_NAME = "shared-knowledge-agent-index"; private static final String HOTEL_KNOWLEDGE_SOURCE_NAME = "shared-knowledge-agent-source"; private static final KnowledgeAgentAzureOpenAIModel OPEN_AI_AGENT_MODEL = new KnowledgeAgentAzureOpenAIModel( - new AzureOpenAIVectorizerParameters() - .setModelName(AzureOpenAIModelName.fromString(OPENAI_MODEL_NAME)) + new AzureOpenAIVectorizerParameters().setModelName(AzureOpenAIModelName.fromString(OPENAI_MODEL_NAME)) .setDeploymentName(OPENAI_DEPLOYMENT_NAME) - .setResourceUrl(OPENAI_ENDPOINT)); + .setResourceUrl(OPENAI_ENDPOINT) + .setAuthIdentity(new SearchIndexerDataUserAssignedIdentity(USER_ASSIGNED_IDENTITY))); private static final List KNOWLEDGE_AGENT_MODELS = Collections.singletonList(OPEN_AI_AGENT_MODEL); private static final List KNOWLEDGE_SOURCE_REFERENCES @@ -85,15 +92,17 @@ public static void setupClass() { searchIndexClient = setupIndex(); waitForIndexing(); + + searchIndexClient.createKnowledgeSource(new SearchIndexKnowledgeSource(HOTEL_KNOWLEDGE_SOURCE_NAME, + new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME))); } @AfterEach public void cleanup() { if (TEST_MODE != TestMode.PLAYBACK) { // Delete Knowledge Agents created during tests. - searchIndexClient.listKnowledgeAgents() - .forEach(knowledgeAgent -> searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName())); + .forEach(agent -> searchIndexClient.deleteKnowledgeAgent(agent.getName())); } } @@ -101,6 +110,10 @@ public void cleanup() { protected static void cleanupClass() { // Clean up any resources after all tests. if (TEST_MODE != TestMode.PLAYBACK) { + // Delete all knowledge agents. + searchIndexClient.listKnowledgeAgents() + .forEach(agent -> searchIndexClient.deleteKnowledgeAgent(agent.getName())); + // Delete the knowledge source created for the tests. searchIndexClient.deleteKnowledgeSource(HOTEL_KNOWLEDGE_SOURCE_NAME); @@ -145,24 +158,22 @@ public void createKnowledgeAgentAsync() { KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); - StepVerifier.create(searchIndexClient.createKnowledgeAgent(knowledgeAgent)) - .assertNext(created -> { - assertEquals(knowledgeAgent.getName(), created.getName()); - - assertEquals(1, created.getModels().size()); - KnowledgeAgentAzureOpenAIModel createdModel - = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, created.getModels().get(0)); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), - createdModel.getAzureOpenAIParameters().getDeploymentName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), - createdModel.getAzureOpenAIParameters().getModelName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), - createdModel.getAzureOpenAIParameters().getResourceUrl()); - - assertEquals(1, created.getKnowledgeSources().size()); - assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, created.getKnowledgeSources().get(0).getName()); - }) - .verifyComplete(); + StepVerifier.create(searchIndexClient.createKnowledgeAgent(knowledgeAgent)).assertNext(created -> { + assertEquals(knowledgeAgent.getName(), created.getName()); + + assertEquals(1, created.getModels().size()); + KnowledgeAgentAzureOpenAIModel createdModel + = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, created.getModels().get(0)); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + createdModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + createdModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + createdModel.getAzureOpenAIParameters().getResourceUrl()); + + assertEquals(1, created.getKnowledgeSources().size()); + assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, created.getKnowledgeSources().get(0).getName()); + }).verifyComplete(); } @Test @@ -196,26 +207,26 @@ public void getKnowledgeAgentAsync() { SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); - searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); - StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) - .assertNext(retrieved -> { - assertEquals(knowledgeAgent.getName(), retrieved.getName()); - - assertEquals(1, retrieved.getModels().size()); - KnowledgeAgentAzureOpenAIModel retrievedModel - = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, retrieved.getModels().get(0)); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), - retrievedModel.getAzureOpenAIParameters().getDeploymentName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), - retrievedModel.getAzureOpenAIParameters().getModelName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), - retrievedModel.getAzureOpenAIParameters().getResourceUrl()); - - assertEquals(1, retrieved.getKnowledgeSources().size()); - assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, retrieved.getKnowledgeSources().get(0).getName()); - }) - .verifyComplete(); + Mono createAndGet = searchIndexClient.createKnowledgeAgent(knowledgeAgent) + .flatMap(created -> searchIndexClient.getKnowledgeAgent(created.getName())); + + StepVerifier.create(createAndGet).assertNext(retrieved -> { + assertEquals(knowledgeAgent.getName(), retrieved.getName()); + + assertEquals(1, retrieved.getModels().size()); + KnowledgeAgentAzureOpenAIModel retrievedModel + = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, retrieved.getModels().get(0)); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + retrievedModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + retrievedModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + retrievedModel.getAzureOpenAIParameters().getResourceUrl()); + + assertEquals(1, retrieved.getKnowledgeSources().size()); + assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, retrieved.getKnowledgeSources().get(0).getName()); + }).verifyComplete(); } @Test @@ -229,7 +240,8 @@ public void listKnowledgeAgentsSync() { = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); searchIndexClient.createKnowledgeAgent(knowledgeAgent2); - Map knowledgeAgentsByName = searchIndexClient.listKnowledgeAgents().stream() + Map knowledgeAgentsByName = searchIndexClient.listKnowledgeAgents() + .stream() .collect(Collectors.toMap(KnowledgeAgent::getName, Function.identity())); assertEquals(2, knowledgeAgentsByName.size() - currentCount); @@ -243,23 +255,27 @@ public void listKnowledgeAgentsSync() { public void listKnowledgeAgentsAsync() { // Test listing knowledge agents. SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); - long currentCount = searchIndexClient.listKnowledgeAgents().count().block(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); KnowledgeAgent knowledgeAgent2 = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); - searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); - searchIndexClient.createKnowledgeAgent(knowledgeAgent2).block(); - - StepVerifier.create(searchIndexClient.listKnowledgeAgents().collectMap(KnowledgeAgent::getName)) - .assertNext(knowledgeAgentsByName -> { - assertEquals(2, knowledgeAgentsByName.size() - currentCount); - KnowledgeAgent listedAgent1 = knowledgeAgentsByName.get(knowledgeAgent.getName()); - assertNotNull(listedAgent1); - KnowledgeAgent listedAgent2 = knowledgeAgentsByName.get(knowledgeAgent2.getName()); - assertNotNull(listedAgent2); - }) - .verifyComplete(); + + Mono>> tuple2Mono = searchIndexClient.listKnowledgeAgents() + .count() + .flatMap(currentCount -> Mono + .when(searchIndexClient.createKnowledgeAgent(knowledgeAgent), + searchIndexClient.createKnowledgeAgent(knowledgeAgent2)) + .then(searchIndexClient.listKnowledgeAgents().collectMap(KnowledgeAgent::getName)) + .map(map -> Tuples.of(currentCount, map))); + + StepVerifier.create(tuple2Mono).assertNext(tuple -> { + Map knowledgeAgentsByName = tuple.getT2(); + assertEquals(2, knowledgeAgentsByName.size() - tuple.getT1()); + KnowledgeAgent listedAgent1 = knowledgeAgentsByName.get(knowledgeAgent.getName()); + assertNotNull(listedAgent1); + KnowledgeAgent listedAgent2 = knowledgeAgentsByName.get(knowledgeAgent2.getName()); + assertNotNull(listedAgent2); + }).verifyComplete(); } @Test @@ -281,15 +297,16 @@ public void deleteKnowledgeAgentAsync() { SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); - searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); - StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) - .assertNext(knowledgeAgent1 -> assertEquals(knowledgeAgent.getName(), knowledgeAgent1.getName())) - .verifyComplete(); + Mono createAndGetMono = searchIndexClient.createKnowledgeAgent(knowledgeAgent) + .flatMap(created -> searchIndexClient.getKnowledgeAgent(created.getName())); - StepVerifier.create(searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName())) + StepVerifier.create(createAndGetMono) + .assertNext(retrieved -> assertEquals(knowledgeAgent.getName(), retrieved.getName())) .verifyComplete(); + StepVerifier.create(searchIndexClient.deleteKnowledgeAgent(knowledgeAgent.getName())).verifyComplete(); + StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) .verifyError(HttpResponseException.class); } @@ -314,17 +331,19 @@ public void updateKnowledgeAgentAsync() { SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); - searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); String newDescription = "Updated description"; - knowledgeAgent.setDescription(newDescription); - searchIndexClient.createOrUpdateKnowledgeAgent(knowledgeAgent).block(); - StepVerifier.create(searchIndexClient.getKnowledgeAgent(knowledgeAgent.getName())) + Mono createUpdateAndGetMono = searchIndexClient.createKnowledgeAgent(knowledgeAgent) + .flatMap(created -> searchIndexClient.createOrUpdateKnowledgeAgent(created.setDescription(newDescription))) + .flatMap(updated -> searchIndexClient.getKnowledgeAgent(updated.getName())); + + StepVerifier.create(createUpdateAndGetMono) .assertNext(retrieved -> assertEquals(newDescription, retrieved.getDescription())) .verifyComplete(); } @Test + @Disabled("Requires further resource deployment") public void basicRetrievalSync() { // Test knowledge agent retrieval functionality. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); @@ -332,12 +351,13 @@ public void basicRetrievalSync() { = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); searchIndexClient.createKnowledgeAgent(knowledgeAgent); - SearchKnowledgeAgentClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(true).buildClient(); + SearchKnowledgeAgentClient knowledgeAgentClient + = getSearchKnowledgeAgentClientBuilder(true).agentName(knowledgeAgent.getName()).buildClient(); KnowledgeAgentMessageTextContent messageTextContent = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); - KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) - .setRole("user"); + KnowledgeAgentMessage message + = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)).setRole("user"); KnowledgeAgentRetrievalRequest retrievalRequest = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); @@ -347,51 +367,56 @@ public void basicRetrievalSync() { } @Test + @Disabled("Requires further resource deployment") public void basicRetrievalAsync() { // Test knowledge agent retrieval functionality. SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES); - searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); - SearchKnowledgeAgentAsyncClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(false) - .buildAsyncClient(); - - KnowledgeAgentMessageTextContent messageTextContent - = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); - KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) - .setRole("user"); - KnowledgeAgentRetrievalRequest retrievalRequest - = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); - - StepVerifier.create(knowledgeAgentClient.retrieve(retrievalRequest, null)) - .assertNext(response -> { - assertNotNull(response); - assertNotNull(response.getResponse()); - }) - .verifyComplete(); + Mono createAndRetrieveMono + = searchIndexClient.createKnowledgeAgent(knowledgeAgent).flatMap(created -> { + SearchKnowledgeAgentAsyncClient knowledgeAgentClient + = getSearchKnowledgeAgentClientBuilder(false).agentName(created.getName()).buildAsyncClient(); + + KnowledgeAgentMessageTextContent messageTextContent + = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); + KnowledgeAgentMessage message + = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)).setRole("user"); + KnowledgeAgentRetrievalRequest retrievalRequest + = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); + + return knowledgeAgentClient.retrieve(retrievalRequest, null); + }); + + StepVerifier.create(createAndRetrieveMono).assertNext(response -> { + assertNotNull(response); + assertNotNull(response.getResponse()); + }).verifyComplete(); } @Test + @Disabled("Requires further resource deployment") public void answerSynthesisRetrievalSync() { // Test knowledge agent retrieval functionality. SearchIndexClient searchIndexClient = getSearchIndexClientBuilder(true).buildClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES) - .setRetrievalInstructions("Only include well reviewed hotels.") - .setOutputConfiguration(new KnowledgeAgentOutputConfiguration() - .setModality(KnowledgeAgentOutputConfigurationModality.ANSWER_SYNTHESIS) - .setAnswerInstructions("Provide a concise answer based on the provided information.") - .setAttemptFastPath(true) - .setIncludeActivity(true)); + .setRetrievalInstructions("Only include well reviewed hotels.") + .setOutputConfiguration(new KnowledgeAgentOutputConfiguration() + .setModality(KnowledgeAgentOutputConfigurationModality.ANSWER_SYNTHESIS) + .setAnswerInstructions("Provide a concise answer based on the provided information.") + .setAttemptFastPath(true) + .setIncludeActivity(true)); searchIndexClient.createKnowledgeAgent(knowledgeAgent); - SearchKnowledgeAgentClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(true).buildClient(); + SearchKnowledgeAgentClient knowledgeAgentClient + = getSearchKnowledgeAgentClientBuilder(true).agentName(knowledgeAgent.getName()).buildClient(); KnowledgeAgentMessageTextContent messageTextContent = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); - KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) - .setRole("user"); + KnowledgeAgentMessage message + = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)).setRole("user"); KnowledgeAgentRetrievalRequest retrievalRequest = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); @@ -402,36 +427,39 @@ public void answerSynthesisRetrievalSync() { } @Test + @Disabled("Requires further resource deployment") public void answerSynthesisRetrievalAsync() { // Test knowledge agent retrieval functionality. SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeAgent knowledgeAgent = new KnowledgeAgent(randomKnowledgeAgentName(), KNOWLEDGE_AGENT_MODELS, KNOWLEDGE_SOURCE_REFERENCES) - .setRetrievalInstructions("Only include well reviewed hotels.") - .setOutputConfiguration(new KnowledgeAgentOutputConfiguration() - .setModality(KnowledgeAgentOutputConfigurationModality.ANSWER_SYNTHESIS) - .setAnswerInstructions("Provide a concise answer based on the provided information.") - .setAttemptFastPath(true) - .setIncludeActivity(true)); - searchIndexClient.createKnowledgeAgent(knowledgeAgent).block(); - - SearchKnowledgeAgentAsyncClient knowledgeAgentClient = getSearchKnowledgeAgentClientBuilder(false) - .buildAsyncClient(); - - KnowledgeAgentMessageTextContent messageTextContent - = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); - KnowledgeAgentMessage message = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)) - .setRole("user"); - KnowledgeAgentRetrievalRequest retrievalRequest - = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); - - StepVerifier.create(knowledgeAgentClient.retrieve(retrievalRequest, null)) - .assertNext(response -> { - assertNotNull(response); - assertNotNull(response.getResponse()); - assertNotNull(response.getActivity()); - }) - .verifyComplete(); + .setRetrievalInstructions("Only include well reviewed hotels.") + .setOutputConfiguration(new KnowledgeAgentOutputConfiguration() + .setModality(KnowledgeAgentOutputConfigurationModality.ANSWER_SYNTHESIS) + .setAnswerInstructions("Provide a concise answer based on the provided information.") + .setAttemptFastPath(true) + .setIncludeActivity(true)); + + Mono createAndRetrieveMono + = searchIndexClient.createKnowledgeAgent(knowledgeAgent).flatMap(created -> { + SearchKnowledgeAgentAsyncClient knowledgeAgentClient + = getSearchKnowledgeAgentClientBuilder(false).agentName(created.getName()).buildAsyncClient(); + + KnowledgeAgentMessageTextContent messageTextContent + = new KnowledgeAgentMessageTextContent("What are the pet policies at the hotel?"); + KnowledgeAgentMessage message + = new KnowledgeAgentMessage(Collections.singletonList(messageTextContent)).setRole("user"); + KnowledgeAgentRetrievalRequest retrievalRequest + = new KnowledgeAgentRetrievalRequest(Collections.singletonList(message)); + + return knowledgeAgentClient.retrieve(retrievalRequest, null); + }); + + StepVerifier.create(createAndRetrieveMono).assertNext(response -> { + assertNotNull(response); + assertNotNull(response.getResponse()); + assertNotNull(response.getActivity()); + }).verifyComplete(); } private String randomKnowledgeAgentName() { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java index d2daab9c978f..2ee3e4a50827 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeSourceTests.java @@ -26,7 +26,10 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import reactor.util.function.Tuple2; +import reactor.util.function.Tuples; import java.io.IOException; import java.io.UncheckedIOException; @@ -107,14 +110,12 @@ public void createKnowledgeSourceAsync() { KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); - StepVerifier.create(searchIndexClient.createKnowledgeSource(knowledgeSource)) - .assertNext(created -> { - assertEquals(knowledgeSource.getName(), created.getName()); + StepVerifier.create(searchIndexClient.createKnowledgeSource(knowledgeSource)).assertNext(created -> { + assertEquals(knowledgeSource.getName(), created.getName()); - SearchIndexKnowledgeSource createdSource = assertInstanceOf(SearchIndexKnowledgeSource.class, created); - assertEquals(HOTEL_INDEX_NAME, createdSource.getSearchIndexParameters().getSearchIndexName()); - }) - .verifyComplete(); + SearchIndexKnowledgeSource createdSource = assertInstanceOf(SearchIndexKnowledgeSource.class, created); + assertEquals(HOTEL_INDEX_NAME, createdSource.getSearchIndexParameters().getSearchIndexName()); + }).verifyComplete(); } @Test @@ -138,16 +139,16 @@ public void getKnowledgeSourceAsync() { SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); - searchIndexClient.createKnowledgeSource(knowledgeSource).block(); - StepVerifier.create(searchIndexClient.getKnowledgeSource(knowledgeSource.getName())) - .assertNext(retrieved -> { - assertEquals(knowledgeSource.getName(), retrieved.getName()); + Mono createAndGetMono = searchIndexClient.createKnowledgeSource(knowledgeSource) + .flatMap(created -> searchIndexClient.getKnowledgeSource(created.getName())); - SearchIndexKnowledgeSource retrievedSource = assertInstanceOf(SearchIndexKnowledgeSource.class, retrieved); - assertEquals(HOTEL_INDEX_NAME, retrievedSource.getSearchIndexParameters().getSearchIndexName()); - }) - .verifyComplete(); + StepVerifier.create(createAndGetMono).assertNext(retrieved -> { + assertEquals(knowledgeSource.getName(), retrieved.getName()); + + SearchIndexKnowledgeSource retrievedSource = assertInstanceOf(SearchIndexKnowledgeSource.class, retrieved); + assertEquals(HOTEL_INDEX_NAME, retrievedSource.getSearchIndexParameters().getSearchIndexName()); + }).verifyComplete(); } @Test @@ -161,7 +162,8 @@ public void listKnowledgeSourcesSync() { new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); searchIndexClient.createKnowledgeSource(knowledgeSource); searchIndexClient.createKnowledgeSource(knowledgeSource2); - Map knowledgeSourcesByName = searchIndexClient.listKnowledgeSources().stream() + Map knowledgeSourcesByName = searchIndexClient.listKnowledgeSources() + .stream() .collect(Collectors.toMap(KnowledgeSource::getName, Function.identity())); assertEquals(2, knowledgeSourcesByName.size() - currentCount); @@ -175,23 +177,27 @@ public void listKnowledgeSourcesSync() { public void listKnowledgeSourceAsync() { // Test listing knowledge sources. SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); - long currentCount = searchIndexClient.listKnowledgeSources().count().block(); KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); KnowledgeSource knowledgeSource2 = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); - searchIndexClient.createKnowledgeSource(knowledgeSource).block(); - searchIndexClient.createKnowledgeSource(knowledgeSource2).block(); - - StepVerifier.create(searchIndexClient.listKnowledgeSources().collectMap(KnowledgeSource::getName)) - .assertNext(knowledgeSourcesByName -> { - assertEquals(2, knowledgeSourcesByName.size() - currentCount); - KnowledgeSource listedSource = knowledgeSourcesByName.get(knowledgeSource.getName()); - assertNotNull(listedSource); - KnowledgeSource listedSource2 = knowledgeSourcesByName.get(knowledgeSource2.getName()); - assertNotNull(listedSource2); - }) - .verifyComplete(); + + Mono>> tuple2Mono = searchIndexClient.listKnowledgeSources() + .count() + .flatMap(currentCount -> Mono + .when(searchIndexClient.createKnowledgeSource(knowledgeSource), + searchIndexClient.createKnowledgeSource(knowledgeSource2)) + .then(searchIndexClient.listKnowledgeSources().collectMap(KnowledgeSource::getName)) + .map(map -> Tuples.of(currentCount, map))); + + StepVerifier.create(tuple2Mono).assertNext(tuple -> { + Map knowledgeSourcesByName = tuple.getT2(); + assertEquals(2, knowledgeSourcesByName.size() - tuple.getT1()); + KnowledgeSource listedSource = knowledgeSourcesByName.get(knowledgeSource.getName()); + assertNotNull(listedSource); + KnowledgeSource listedSource2 = knowledgeSourcesByName.get(knowledgeSource2.getName()); + assertNotNull(listedSource2); + }).verifyComplete(); } @Test @@ -215,9 +221,11 @@ public void deleteKnowledgeSourceAsync() { SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); - searchIndexClient.createKnowledgeSource(knowledgeSource).block(); - StepVerifier.create(searchIndexClient.getKnowledgeSource(knowledgeSource.getName())) + Mono createAndGetMono = searchIndexClient.createKnowledgeSource(knowledgeSource) + .flatMap(created -> searchIndexClient.getKnowledgeSource(created.getName())); + + StepVerifier.create(createAndGetMono) .assertNext(retrieved -> assertEquals(knowledgeSource.getName(), retrieved.getName())) .verifyComplete(); @@ -247,12 +255,13 @@ public void updateKnowledgeSourceAsync() { SearchIndexAsyncClient searchIndexClient = getSearchIndexClientBuilder(false).buildAsyncClient(); KnowledgeSource knowledgeSource = new SearchIndexKnowledgeSource(randomKnowledgeSourceName(), new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME)); - searchIndexClient.createKnowledgeSource(knowledgeSource).block(); String newDescription = "Updated description"; - knowledgeSource.setDescription(newDescription); - searchIndexClient.createOrUpdateKnowledgeSource(knowledgeSource).block(); - StepVerifier.create(searchIndexClient.getKnowledgeSource(knowledgeSource.getName())) + Mono createUpdateAndGetMono = searchIndexClient.createKnowledgeSource(knowledgeSource) + .flatMap(created -> searchIndexClient.createOrUpdateKnowledgeSource(created.setDescription(newDescription))) + .flatMap(updated -> searchIndexClient.getKnowledgeSource(updated.getName())); + + StepVerifier.create(createUpdateAndGetMono) .assertNext(retrieved -> assertEquals(newDescription, retrieved.getDescription())) .verifyComplete(); } @@ -274,9 +283,9 @@ private static SearchIndexClient setupIndex() { List semanticConfigurations = Collections.singletonList(new SemanticConfiguration("semantic-config", - new SemanticPrioritizedFields().setTitleField(new SemanticField("HotelName")) - .setContentFields(new SemanticField("Description")) - .setKeywordsFields(new SemanticField("Category")))); + new SemanticPrioritizedFields().setTitleField(new SemanticField("HotelName")) + .setContentFields(new SemanticField("Description")) + .setKeywordsFields(new SemanticField("Category")))); SemanticSearch semanticSearch = new SemanticSearch().setDefaultConfigurationName("semantic-config") .setConfigurations(semanticConfigurations); searchIndexClient.createOrUpdateIndex( diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java index a43d207f4b91..44284f9d855b 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchIndexingBufferedSenderUnitTests.java @@ -71,7 +71,9 @@ public class SearchIndexingBufferedSenderUnitTests { } private static SearchClientBuilder getSearchClientBuilder() { - return new SearchClientBuilder().endpoint(SEARCH_ENDPOINT).indexName("index").credential(getTestTokenCredential()); + return new SearchClientBuilder().endpoint(SEARCH_ENDPOINT) + .indexName("index") + .credential(getTestTokenCredential()); } private static HttpClient wrapWithAsserting(HttpClient wrappedHttpClient, boolean isSync) { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java index f09ae3680111..8218bfca61b3 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java @@ -15,6 +15,8 @@ import com.azure.core.test.TestMode; import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.http.AssertingHttpClientBuilder; +import com.azure.core.test.models.TestProxySanitizer; +import com.azure.core.test.models.TestProxySanitizerType; import com.azure.core.util.Configuration; import com.azure.core.util.logging.ClientLogger; import com.azure.json.JsonProviders; @@ -78,22 +80,35 @@ public abstract class SearchTestBase extends TestProxyTestBase { protected static final String SEARCH_ENDPOINT = Configuration.getGlobalConfiguration().get("SEARCH_SERVICE_ENDPOINT", "https://playback.search.windows.net"); - protected static final String OPENAI_ENDPOINT = Configuration.getGlobalConfiguration() - .get("SEARCH_OPENAI_ENDPOINT", "https://your-endpoint.openai.azure.com"); - protected static final String OPENAI_DEPLOYMENT_NAME = Configuration.getGlobalConfiguration() - .get("SEARCH_OPENAI_DEPLOYMENT_NAME", "deployment-name"); - protected static final String OPENAI_MODEL_NAME = Configuration.getGlobalConfiguration() - .get("SEARCH_OPENAI_MODEL_NAME", "model-name"); + protected static final String OPENAI_ENDPOINT; + static { + String openAiEndpoint = Configuration.getGlobalConfiguration() + .get("SEARCH_OPENAI_ENDPOINT", "https://your-endpoint.openai.azure.com"); + // Service trims trailing '/', need to do that here so tests don't fail. + if (openAiEndpoint.endsWith("/")) { + openAiEndpoint = openAiEndpoint.substring(0, openAiEndpoint.length() - 1); + } + + OPENAI_ENDPOINT = openAiEndpoint; + } + + protected static final String OPENAI_DEPLOYMENT_NAME + = Configuration.getGlobalConfiguration().get("SEARCH_OPENAI_DEPLOYMENT_NAME", "deployment-name"); + protected static final String OPENAI_MODEL_NAME + = Configuration.getGlobalConfiguration().get("SEARCH_OPENAI_MODEL_NAME", "model-name"); - protected static final String STORAGE_ACCOUNT_NAME = Configuration.getGlobalConfiguration() - .get("SEARCH_STORAGE_ACCOUNT_NAME", "storageaccount"); - protected static final String BLOB_CONTAINER_NAME = Configuration.getGlobalConfiguration() - .get("SEARCH_STORAGE_CONTAINER_NAME", "searchcontainer"); + protected static final String STORAGE_ACCOUNT_NAME + = Configuration.getGlobalConfiguration().get("SEARCH_STORAGE_ACCOUNT_NAME", "storageaccount"); + protected static final String BLOB_CONTAINER_NAME + = Configuration.getGlobalConfiguration().get("SEARCH_STORAGE_CONTAINER_NAME", "searchcontainer"); - protected static final String SUBSCRIPTION_ID = Configuration.getGlobalConfiguration() - .get(Configuration.PROPERTY_AZURE_SUBSCRIPTION_ID, "subscription-id"); - protected static final String RESOURCE_GROUP = Configuration.getGlobalConfiguration() - .get(Configuration.PROPERTY_AZURE_RESOURCE_GROUP, "resource-group"); + protected static final String USER_ASSIGNED_IDENTITY = Configuration.getGlobalConfiguration() + .get("SEARCH_USER_ASSIGNED_IDENTITY", "/subscriptions/subscription-id/resourceGroups/resource-group-name/" + + "providers/Microsoft.ManagedIdentity/userAssignedIdentities/user-assigned-managed-identity-name"); + protected static final String SUBSCRIPTION_ID + = Configuration.getGlobalConfiguration().get("SEARCH_SUBSCRIPTION_ID", "subscription-id"); + protected static final String RESOURCE_GROUP + = Configuration.getGlobalConfiguration().get("SEARCH_RESOURCE_GROUP", "resource-group"); protected static final TestMode TEST_MODE = initializeTestMode(); @@ -105,8 +120,8 @@ public abstract class SearchTestBase extends TestProxyTestBase { // Change the delay based on the mode. static final RetryPolicy SERVICE_THROTTLE_SAFE_RETRY_POLICY = new RetryPolicy( new FixedDelay(4, TEST_MODE == TestMode.PLAYBACK ? Duration.ofMillis(1) : Duration.ofSeconds(60))); - static final RetryOptions SERVICE_THROTTLE_SAFE_RETRY_OPTIONS = new RetryOptions(new FixedDelayOptions(4, - TEST_MODE == TestMode.PLAYBACK ? Duration.ofMillis(1) : Duration.ofSeconds(60))); + static final RetryOptions SERVICE_THROTTLE_SAFE_RETRY_OPTIONS = new RetryOptions( + new FixedDelayOptions(4, TEST_MODE == TestMode.PLAYBACK ? Duration.ofMillis(1) : Duration.ofSeconds(60))); protected String createHotelIndex() { return setupIndexFromJsonFile(); @@ -148,6 +163,8 @@ protected SearchIndexClientBuilder getSearchIndexClientBuilder(boolean isSync) { } if (interceptorManager.isRecordMode()) { + interceptorManager.addSanitizers( + new TestProxySanitizer("$..userAssignedIdentity", null, "REDACTED", TestProxySanitizerType.BODY_KEY)); builder.addPolicy(interceptorManager.getRecordPolicy()); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java index 26b721c1f4ef..07dceef708e3 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchWithSharedIndexTests.java @@ -50,13 +50,14 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import static com.azure.search.documents.TestHelpers.waitForIndexing; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Tests vector search capabilities using a shared index created before testing begins. @@ -165,9 +166,8 @@ public void simpleHybridSearchAsync() { .setSelect("HotelId", "HotelName"); StepVerifier.create(searchClient.search("Top hotels in town", searchOptions).collectList()) - .assertNext( - results -> assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), - "3", "1", "5", "2", "10", "4", "9")) + .assertNext(results -> assertKeysEqual(results, + r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "3", "1", "5", "2", "10", "4", "9")) .verifyComplete(); } @@ -204,27 +204,27 @@ public void semanticHybridSearchAsync() { searchOptions) .byPage() .collectList()).assertNext(pages -> { - SearchPagedResponse page1 = pages.get(0); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1)); - assertEquals(1, SearchPagedResponseAccessHelper.getQueryAnswers(page1).size()); - assertEquals("9", SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getKey()); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getHighlights()); - assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getText()); - - List results = new ArrayList<>(); - for (SearchPagedResponse page : pages) { - for (SearchResult result : page.getValue()) { - results.add(result); - - assertNotNull(result.getSemanticSearch().getQueryCaptions()); - assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getHighlights()); - assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getText()); + SearchPagedResponse page1 = pages.get(0); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1)); + assertEquals(1, SearchPagedResponseAccessHelper.getQueryAnswers(page1).size()); + assertEquals("9", SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getKey()); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getHighlights()); + assertNotNull(SearchPagedResponseAccessHelper.getQueryAnswers(page1).get(0).getText()); + + List results = new ArrayList<>(); + for (SearchPagedResponse page : pages) { + for (SearchResult result : page.getValue()) { + results.add(result); + + assertNotNull(result.getSemanticSearch().getQueryCaptions()); + assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getHighlights()); + assertNotNull(result.getSemanticSearch().getQueryCaptions().get(0).getText()); + } } - } - assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "9", "3", "2", - "5", "10", "1", "4"); - }).verifyComplete(); + assertKeysEqual(results, r -> (String) r.getDocument(SearchDocument.class).get("HotelId"), "9", "3", + "2", "5", "10", "1", "4"); + }).verifyComplete(); } @Test @@ -275,8 +275,8 @@ public void hybridSearchWithVectorFilterOverrideSync() { // create a hybrid search query with a vector search query and a regular search query SearchOptions searchOptions = new SearchOptions().setFilter("Rating ge 3") .setSelect("HotelId", "HotelName", "Rating") - .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery() - .setFilterOverride("HotelId eq '1'"))); + .setVectorSearchOptions(new VectorSearchOptions() + .setQueries(createDescriptionVectorQuery().setFilterOverride("HotelId eq '1'"))); // run the hybrid search query SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); @@ -294,26 +294,24 @@ public void hybridSearchWithVectorFilterOverrideAsync() { // create a hybrid search query with a vector search query and a regular search query SearchOptions searchOptions = new SearchOptions().setFilter("Rating ge 3") .setSelect("HotelId", "HotelName", "Rating") - .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery() - .setFilterOverride("HotelId eq '1'"))); + .setVectorSearchOptions(new VectorSearchOptions() + .setQueries(createDescriptionVectorQuery().setFilterOverride("HotelId eq '1'"))); // run the hybrid search query SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); - StepVerifier.create(searchClient.search("fancy", searchOptions).collectList()) - .assertNext(results -> { - // check that the results are as expected - assertEquals(1, results.size()); - assertEquals("1", results.get(0).getDocument(SearchDocument.class).get("HotelId")); - }) - .verifyComplete(); + StepVerifier.create(searchClient.search("fancy", searchOptions).collectList()).assertNext(results -> { + // check that the results are as expected + assertEquals(1, results.size()); + assertEquals("1", results.get(0).getDocument(SearchDocument.class).get("HotelId")); + }).verifyComplete(); } @Test public void vectorSearchWithPostFilterModeSync() { SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() - .setQueries(createDescriptionVectorQuery()) + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery()) .setFilterMode(VectorFilterMode.POST_FILTER)) .setSelect("HotelId", "HotelName"); @@ -327,8 +325,8 @@ public void vectorSearchWithPostFilterModeSync() { public void vectorSearchWithPostFilterModeAsync() { SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() - .setQueries(createDescriptionVectorQuery()) + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery()) .setFilterMode(VectorFilterMode.POST_FILTER)) .setSelect("HotelId", "HotelName"); @@ -342,8 +340,8 @@ public void vectorSearchWithPostFilterModeAsync() { public void vectorSearchWithStrictPostFilterModeSync() { SearchClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, true).buildClient(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() - .setQueries(createDescriptionVectorQuery()) + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery()) .setFilterMode(VectorFilterMode.STRICT_POST_FILTER)) .setSelect("HotelId", "HotelName"); @@ -357,8 +355,8 @@ public void vectorSearchWithStrictPostFilterModeSync() { public void vectorSearchWithStrictPostFilterModeAsync() { SearchAsyncClient searchClient = getSearchClientBuilder(HOTEL_INDEX_NAME, false).buildAsyncClient(); - SearchOptions searchOptions = new SearchOptions().setVectorSearchOptions(new VectorSearchOptions() - .setQueries(createDescriptionVectorQuery()) + SearchOptions searchOptions = new SearchOptions() + .setVectorSearchOptions(new VectorSearchOptions().setQueries(createDescriptionVectorQuery()) .setFilterMode(VectorFilterMode.STRICT_POST_FILTER)) .setSelect("HotelId", "HotelName"); @@ -373,9 +371,18 @@ private static VectorQuery createDescriptionVectorQuery() { .setFields("DescriptionVector"); } + /* + * Helper method that checks that all expected keys are contained in the results. + * This does not validate the order of the keys as small changes to configurations can drastically change results. + */ private static void assertKeysEqual(List results, Function keyAccessor, String... expectedKeys) { - assertArrayEquals(expectedKeys, results.stream().map(keyAccessor).toArray()); + Set keySet = results.stream().map(keyAccessor).collect(Collectors.toSet()); + + assertEquals(expectedKeys.length, keySet.size()); + assertTrue(keySet.containsAll(Arrays.asList(expectedKeys)), + () -> String.format("Result key set didn't contain all expected keys. Expected: '%s', Actual: '%s'", + String.join(", ", expectedKeys), String.join(", ", keySet))); } private static SearchIndex getVectorIndex() { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java index a3ab56d30688..57dfc7c21222 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexersManagementTests.java @@ -25,11 +25,11 @@ import com.azure.search.documents.indexes.models.SearchIndexerDataContainer; import com.azure.search.documents.indexes.models.SearchIndexerDataSourceConnection; import com.azure.search.documents.indexes.models.SearchIndexerDataSourceType; +import com.azure.search.documents.indexes.models.SearchIndexerDataUserAssignedIdentity; import com.azure.search.documents.indexes.models.SearchIndexerLimits; import com.azure.search.documents.indexes.models.SearchIndexerSkill; import com.azure.search.documents.indexes.models.SearchIndexerSkillset; import com.azure.search.documents.indexes.models.SearchIndexerStatus; -import com.azure.search.documents.indexes.models.SoftDeleteColumnDeletionDetectionPolicy; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -1157,13 +1157,11 @@ private static SearchIndexerDataSourceConnection createSharedDataSource() { return new SearchIndexerDataSourceConnection("shared-" + BLOB_DATASOURCE_NAME) .setType(SearchIndexerDataSourceType.AZURE_BLOB) .setDescription("real live blob") + .setIdentity(new SearchIndexerDataUserAssignedIdentity(USER_ASSIGNED_IDENTITY)) .setConnectionString(String.format( "ResourceId=/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s;", - SUBSCRIPTION_ID, RESOURCE_GROUP, STORAGE_ACCOUNT_NAME)) - .setContainer(new SearchIndexerDataContainer(BLOB_CONTAINER_NAME).setQuery("/")) - .setDataDeletionDetectionPolicy( - new SoftDeleteColumnDeletionDetectionPolicy().setSoftDeleteColumnName("fieldName") - .setSoftDeleteMarkerValue("someValue")); + SUBSCRIPTION_ID, RESOURCE_GROUP, STORAGE_ACCOUNT_NAME)) + .setContainer(new SearchIndexerDataContainer(BLOB_CONTAINER_NAME).setQuery("/")); } SearchIndexer createBaseTestIndexerObject(String targetIndexName, String dataSourceName) { diff --git a/sdk/search/test-resources.bicep b/sdk/search/test-resources.bicep index 573e0ad906e2..af57ad08cf9b 100644 --- a/sdk/search/test-resources.bicep +++ b/sdk/search/test-resources.bicep @@ -25,8 +25,10 @@ param searchEndpointSuffix string = 'search.windows.net' param searchSku string = 'basic' // Variables -var searchServiceName = 'azs-java-${baseName}' -var storageAccountName = substring('search${baseName}', 0, 24) +var guidSeed = guid(baseName) +var unique = uniqueString(guidSeed) +var searchServiceName = 'azs-java-${unique}' +var storageAccountName = 'search${unique}' // Static resource group name for TME tenant var staticResourceGroupName = 'static-test-resources' @@ -158,7 +160,7 @@ resource storageBlobDataReaderRoleDefinition 'Microsoft.Authorization/roleDefini // Storage Blob Data Contributor role definition resource storageBlobDataContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { scope: subscription() - // This is the Storage Blob Contributor Reader role + // This is the Storage Blob Data Contributor role // See https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#storage-blob-data-contributor name: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' } @@ -166,7 +168,7 @@ resource storageBlobDataContributorRoleDefinition 'Microsoft.Authorization/roleD // Search Index Data Contributor role definition resource searchIndexDataContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { scope: subscription() - // This is the Search Index Data Reader role + // This is the Search Index Data Contributor role // See https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#search-index-data-contributor name: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' } @@ -250,3 +252,6 @@ output SEARCH_OPENAI_DEPLOYMENT_NAME string = isTmeTenant output SEARCH_OPENAI_MODEL_NAME string = isTmeTenant ? openaiStatic::openaiStaticDeployment.properties.model.name : openai::openaiDeployment.properties.model.name +output SEARCH_USER_ASSIGNED_IDENTITY string = isTmeTenant + ? '/subscriptions/${subscription().subscriptionId}/resourceGroups/${staticResourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${staticSearchServiceIdentity.name}' + : '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${searchServiceIdentity.name}' From d1204c786f508537370e2ee29c6b37ad6a9cc612 Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:01:55 -0400 Subject: [PATCH 09/12] Update tests to handle deployment supplied data --- sdk/search/azure-search-documents/assets.json | 2 +- .../search/documents/KnowledgeAgentTests.java | 17 +++++++++++++++++ .../azure/search/documents/SearchTestBase.java | 4 ---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sdk/search/azure-search-documents/assets.json b/sdk/search/azure-search-documents/assets.json index 0badaf2c915d..25de395cc455 100644 --- a/sdk/search/azure-search-documents/assets.json +++ b/sdk/search/azure-search-documents/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "java", "TagPrefix": "java/search/azure-search-documents", - "Tag": "java/search/azure-search-documents_3d1f64a492" + "Tag": "java/search/azure-search-documents_93e02a04a0" } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java index 89d4c79e2d12..8cc80d90c1c3 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java @@ -7,6 +7,10 @@ import com.azure.core.http.policy.HttpLogOptions; import com.azure.core.test.TestMode; import com.azure.core.test.TestProxyTestBase; +import com.azure.core.test.models.BodilessMatcher; +import com.azure.core.test.models.TestProxySanitizer; +import com.azure.core.test.models.TestProxySanitizerType; +import com.azure.core.test.utils.TestProxyUtils; import com.azure.json.JsonProviders; import com.azure.json.JsonReader; import com.azure.search.documents.agents.SearchKnowledgeAgentAsyncClient; @@ -37,6 +41,7 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -97,6 +102,18 @@ public static void setupClass() { new SearchIndexKnowledgeSourceParameters(HOTEL_INDEX_NAME))); } + @BeforeEach + public void setup() { + interceptorManager.addMatchers(new BodilessMatcher()); + + if (!interceptorManager.isLiveMode()) { + interceptorManager.addSanitizers( + new TestProxySanitizer("$..userAssignedIdentity", null, "REDACTED", TestProxySanitizerType.BODY_KEY), + new TestProxySanitizer("$..azureOpenAIParameters.resourceUri", TestProxyUtils.HOST_NAME_REGEX, + "REDACTED", TestProxySanitizerType.BODY_KEY)); + } + } + @AfterEach public void cleanup() { if (TEST_MODE != TestMode.PLAYBACK) { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java index 8218bfca61b3..38d29762c0a9 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java @@ -15,8 +15,6 @@ import com.azure.core.test.TestMode; import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.http.AssertingHttpClientBuilder; -import com.azure.core.test.models.TestProxySanitizer; -import com.azure.core.test.models.TestProxySanitizerType; import com.azure.core.util.Configuration; import com.azure.core.util.logging.ClientLogger; import com.azure.json.JsonProviders; @@ -163,8 +161,6 @@ protected SearchIndexClientBuilder getSearchIndexClientBuilder(boolean isSync) { } if (interceptorManager.isRecordMode()) { - interceptorManager.addSanitizers( - new TestProxySanitizer("$..userAssignedIdentity", null, "REDACTED", TestProxySanitizerType.BODY_KEY)); builder.addPolicy(interceptorManager.getRecordPolicy()); } From a965943f46f8ce76be98a804b126e22a6221d672 Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Tue, 2 Sep 2025 10:58:29 -0400 Subject: [PATCH 10/12] Update Swagger SHAs, add back missing features --- .../models/KnowledgeAgentActivityRecord.java | 2 - .../models/KnowledgeAgentReference.java | 2 - ...KnowledgeAgentRetrievalActivityRecord.java | 2 - .../KnowledgeAgentWebActivityArguments.java | 126 ----- .../KnowledgeAgentWebActivityRecord.java | 196 ------- .../models/KnowledgeAgentWebReference.java | 180 ------ .../agents/models/KnowledgeSourceKind.java | 6 - .../agents/models/KnowledgeSourceParams.java | 2 - .../implementation/util/FieldBuilder.java | 20 +- .../implementation/util/MappingUtils.java | 89 ++- .../indexes/SearchIndexAsyncClient.java | 276 +++++++++- .../documents/indexes/SearchIndexClient.java | 276 +++++++++- .../indexes/SearchIndexerAsyncClient.java | 304 +++++++++- .../indexes/SearchIndexerClient.java | 245 ++++++++- .../documents/indexes/SearchableField.java | 9 + .../search/documents/indexes/SimpleField.java | 9 + ...teOrUpdateDataSourceConnectionOptions.java | 88 +++ .../models/CreateOrUpdateIndexerOptions.java | 109 ++++ .../models/CreateOrUpdateSkillsetOptions.java | 109 ++++ .../indexes/models/KnowledgeSource.java | 2 - .../indexes/models/KnowledgeSourceKind.java | 6 - .../documents/indexes/models/SearchField.java | 4 +- .../indexes/models/WebKnowledgeSource.java | 177 ------ .../WebKnowledgeSourceAllowedDomain.java | 160 ------ .../WebKnowledgeSourceBlockedDomain.java | 126 ----- .../models/WebKnowledgeSourceParameters.java | 287 ---------- .../WebKnowledgeSourceRankingAdjustment.java | 67 --- .../documents/SearchJavaDocCodeSnippets.java | 518 +++++++++++++++++- .../search/documents/SearchAliasTests.java | 374 +++++++++++++ .../documents/indexes/FieldBuilderTests.java | 40 ++ .../documents/indexes/NonRestCallTests.java | 6 +- .../documents/indexes/OptionBagsTests.java | 118 ++++ .../SearchRequestUrlRewriterPolicyTests.java | 33 +- .../azure-search-documents/swagger/README.md | 12 +- 34 files changed, 2535 insertions(+), 1445 deletions(-) delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java create mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSource.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java create mode 100644 sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java create mode 100644 sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java index f2a23c197c82..0b6e697ebcbd 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentActivityRecord.java @@ -134,8 +134,6 @@ public static KnowledgeAgentActivityRecord fromJson(JsonReader jsonReader) throw return KnowledgeAgentSearchIndexActivityRecord.fromJson(readerToUse.reset()); } else if ("azureBlob".equals(discriminatorValue)) { return KnowledgeAgentAzureBlobActivityRecord.fromJson(readerToUse.reset()); - } else if ("web".equals(discriminatorValue)) { - return KnowledgeAgentWebActivityRecord.fromJson(readerToUse.reset()); } else if ("modelQueryPlanning".equals(discriminatorValue)) { return KnowledgeAgentModelQueryPlanningActivityRecord.fromJson(readerToUse.reset()); } else if ("modelAnswerSynthesis".equals(discriminatorValue)) { diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java index 49a9ef4cd81c..3e561a013d53 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentReference.java @@ -183,8 +183,6 @@ public static KnowledgeAgentReference fromJson(JsonReader jsonReader) throws IOE return KnowledgeAgentSearchIndexReference.fromJson(readerToUse.reset()); } else if ("azureBlob".equals(discriminatorValue)) { return KnowledgeAgentAzureBlobReference.fromJson(readerToUse.reset()); - } else if ("web".equals(discriminatorValue)) { - return KnowledgeAgentWebReference.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java index 5b9607d1e890..63e7d5002e14 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentRetrievalActivityRecord.java @@ -191,8 +191,6 @@ public static KnowledgeAgentRetrievalActivityRecord fromJson(JsonReader jsonRead return KnowledgeAgentSearchIndexActivityRecord.fromJson(readerToUse.reset()); } else if ("azureBlob".equals(discriminatorValue)) { return KnowledgeAgentAzureBlobActivityRecord.fromJson(readerToUse.reset()); - } else if ("web".equals(discriminatorValue)) { - return KnowledgeAgentWebActivityRecord.fromJson(readerToUse.reset()); } else { return fromJsonKnownDiscriminator(readerToUse.reset()); } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java deleted file mode 100644 index 9cf9ec98bb45..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityArguments.java +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.agents.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Represents the arguments the web retrieval activity was run with. - */ -@Fluent -public final class KnowledgeAgentWebActivityArguments implements JsonSerializable { - /* - * The search string used to query the web. - */ - @Generated - private String search; - - /* - * The freshness for the retrieval activity. - */ - @Generated - private String freshness; - - /** - * Creates an instance of KnowledgeAgentWebActivityArguments class. - */ - @Generated - public KnowledgeAgentWebActivityArguments() { - } - - /** - * Get the search property: The search string used to query the web. - * - * @return the search value. - */ - @Generated - public String getSearch() { - return this.search; - } - - /** - * Set the search property: The search string used to query the web. - * - * @param search the search value to set. - * @return the KnowledgeAgentWebActivityArguments object itself. - */ - @Generated - public KnowledgeAgentWebActivityArguments setSearch(String search) { - this.search = search; - return this; - } - - /** - * Get the freshness property: The freshness for the retrieval activity. - * - * @return the freshness value. - */ - @Generated - public String getFreshness() { - return this.freshness; - } - - /** - * Set the freshness property: The freshness for the retrieval activity. - * - * @param freshness the freshness value to set. - * @return the KnowledgeAgentWebActivityArguments object itself. - */ - @Generated - public KnowledgeAgentWebActivityArguments setFreshness(String freshness) { - this.freshness = freshness; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("search", this.search); - jsonWriter.writeStringField("freshness", this.freshness); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of KnowledgeAgentWebActivityArguments from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of KnowledgeAgentWebActivityArguments if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the KnowledgeAgentWebActivityArguments. - */ - @Generated - public static KnowledgeAgentWebActivityArguments fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - KnowledgeAgentWebActivityArguments deserializedKnowledgeAgentWebActivityArguments - = new KnowledgeAgentWebActivityArguments(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("search".equals(fieldName)) { - deserializedKnowledgeAgentWebActivityArguments.search = reader.getString(); - } else if ("freshness".equals(fieldName)) { - deserializedKnowledgeAgentWebActivityArguments.freshness = reader.getString(); - } else { - reader.skipChildren(); - } - } - - return deserializedKnowledgeAgentWebActivityArguments; - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java deleted file mode 100644 index 9bfb61f3dc73..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebActivityRecord.java +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.agents.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.core.util.CoreUtils; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; - -/** - * Represents a web retrieval activity record. - */ -@Fluent -public final class KnowledgeAgentWebActivityRecord extends KnowledgeAgentRetrievalActivityRecord { - /* - * The type of the activity record. - */ - @Generated - private String type = "web"; - - /* - * The web arguments for the retrieval activity. - */ - @Generated - private KnowledgeAgentWebActivityArguments webArguments; - - /** - * Creates an instance of KnowledgeAgentWebActivityRecord class. - * - * @param id the id value to set. - */ - @Generated - public KnowledgeAgentWebActivityRecord(int id) { - super(id); - } - - /** - * Get the type property: The type of the activity record. - * - * @return the type value. - */ - @Generated - @Override - public String getType() { - return this.type; - } - - /** - * Get the webArguments property: The web arguments for the retrieval activity. - * - * @return the webArguments value. - */ - @Generated - public KnowledgeAgentWebActivityArguments getWebArguments() { - return this.webArguments; - } - - /** - * Set the webArguments property: The web arguments for the retrieval activity. - * - * @param webArguments the webArguments value to set. - * @return the KnowledgeAgentWebActivityRecord object itself. - */ - @Generated - public KnowledgeAgentWebActivityRecord setWebArguments(KnowledgeAgentWebActivityArguments webArguments) { - this.webArguments = webArguments; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public KnowledgeAgentWebActivityRecord setKnowledgeSourceName(String knowledgeSourceName) { - super.setKnowledgeSourceName(knowledgeSourceName); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public KnowledgeAgentWebActivityRecord setQueryTime(OffsetDateTime queryTime) { - super.setQueryTime(queryTime); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public KnowledgeAgentWebActivityRecord setCount(Integer count) { - super.setCount(count); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public KnowledgeAgentWebActivityRecord setElapsedMs(Integer elapsedMs) { - super.setElapsedMs(elapsedMs); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeIntField("id", getId()); - jsonWriter.writeNumberField("elapsedMs", getElapsedMs()); - jsonWriter.writeStringField("knowledgeSourceName", getKnowledgeSourceName()); - jsonWriter.writeStringField("queryTime", - getQueryTime() == null ? null : DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(getQueryTime())); - jsonWriter.writeNumberField("count", getCount()); - jsonWriter.writeStringField("type", this.type); - jsonWriter.writeJsonField("webArguments", this.webArguments); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of KnowledgeAgentWebActivityRecord from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of KnowledgeAgentWebActivityRecord if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the KnowledgeAgentWebActivityRecord. - */ - @Generated - public static KnowledgeAgentWebActivityRecord fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - boolean idFound = false; - int id = 0; - Integer elapsedMs = null; - String knowledgeSourceName = null; - OffsetDateTime queryTime = null; - Integer count = null; - String type = "web"; - KnowledgeAgentWebActivityArguments webArguments = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("id".equals(fieldName)) { - id = reader.getInt(); - idFound = true; - } else if ("elapsedMs".equals(fieldName)) { - elapsedMs = reader.getNullable(JsonReader::getInt); - } else if ("knowledgeSourceName".equals(fieldName)) { - knowledgeSourceName = reader.getString(); - } else if ("queryTime".equals(fieldName)) { - queryTime = reader - .getNullable(nonNullReader -> CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); - } else if ("count".equals(fieldName)) { - count = reader.getNullable(JsonReader::getInt); - } else if ("type".equals(fieldName)) { - type = reader.getString(); - } else if ("webArguments".equals(fieldName)) { - webArguments = KnowledgeAgentWebActivityArguments.fromJson(reader); - } else { - reader.skipChildren(); - } - } - if (idFound) { - KnowledgeAgentWebActivityRecord deserializedKnowledgeAgentWebActivityRecord - = new KnowledgeAgentWebActivityRecord(id); - deserializedKnowledgeAgentWebActivityRecord.setElapsedMs(elapsedMs); - deserializedKnowledgeAgentWebActivityRecord.setKnowledgeSourceName(knowledgeSourceName); - deserializedKnowledgeAgentWebActivityRecord.setQueryTime(queryTime); - deserializedKnowledgeAgentWebActivityRecord.setCount(count); - deserializedKnowledgeAgentWebActivityRecord.type = type; - deserializedKnowledgeAgentWebActivityRecord.webArguments = webArguments; - - return deserializedKnowledgeAgentWebActivityRecord; - } - throw new IllegalStateException("Missing required property: id"); - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java deleted file mode 100644 index 703d60ae7339..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeAgentWebReference.java +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.agents.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Represents a web document reference. - */ -@Fluent -public final class KnowledgeAgentWebReference extends KnowledgeAgentReference { - /* - * The type of the reference. - */ - @Generated - private String type = "web"; - - /* - * The url the reference data originated from. - */ - @Generated - private String url; - - /** - * Creates an instance of KnowledgeAgentWebReference class. - * - * @param id the id value to set. - * @param activitySource the activitySource value to set. - */ - @Generated - public KnowledgeAgentWebReference(String id, int activitySource) { - super(id, activitySource); - } - - /** - * Get the type property: The type of the reference. - * - * @return the type value. - */ - @Generated - @Override - public String getType() { - return this.type; - } - - /** - * Get the url property: The url the reference data originated from. - * - * @return the url value. - */ - @Generated - public String getUrl() { - return this.url; - } - - /** - * Set the url property: The url the reference data originated from. - * - * @param url the url value to set. - * @return the KnowledgeAgentWebReference object itself. - */ - @Generated - public KnowledgeAgentWebReference setUrl(String url) { - this.url = url; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public KnowledgeAgentWebReference setSourceData(Map sourceData) { - super.setSourceData(sourceData); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public KnowledgeAgentWebReference setRerankerScore(Float rerankerScore) { - super.setRerankerScore(rerankerScore); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("id", getId()); - jsonWriter.writeIntField("activitySource", getActivitySource()); - jsonWriter.writeMapField("sourceData", getSourceData(), (writer, element) -> writer.writeUntyped(element)); - jsonWriter.writeNumberField("rerankerScore", getRerankerScore()); - jsonWriter.writeStringField("type", this.type); - jsonWriter.writeStringField("url", this.url); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of KnowledgeAgentWebReference from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of KnowledgeAgentWebReference if the JsonReader was pointing to an instance of it, or null if - * it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the KnowledgeAgentWebReference. - */ - @Generated - public static KnowledgeAgentWebReference fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - boolean idFound = false; - String id = null; - boolean activitySourceFound = false; - int activitySource = 0; - Map sourceData = null; - Float rerankerScore = null; - String type = "web"; - String url = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("id".equals(fieldName)) { - id = reader.getString(); - idFound = true; - } else if ("activitySource".equals(fieldName)) { - activitySource = reader.getInt(); - activitySourceFound = true; - } else if ("sourceData".equals(fieldName)) { - sourceData = reader.readMap(reader1 -> reader1.readUntyped()); - } else if ("rerankerScore".equals(fieldName)) { - rerankerScore = reader.getNullable(JsonReader::getFloat); - } else if ("type".equals(fieldName)) { - type = reader.getString(); - } else if ("url".equals(fieldName)) { - url = reader.getString(); - } else { - reader.skipChildren(); - } - } - if (idFound && activitySourceFound) { - KnowledgeAgentWebReference deserializedKnowledgeAgentWebReference - = new KnowledgeAgentWebReference(id, activitySource); - deserializedKnowledgeAgentWebReference.setSourceData(sourceData); - deserializedKnowledgeAgentWebReference.setRerankerScore(rerankerScore); - deserializedKnowledgeAgentWebReference.type = type; - deserializedKnowledgeAgentWebReference.url = url; - - return deserializedKnowledgeAgentWebReference; - } - List missingProperties = new ArrayList<>(); - if (!idFound) { - missingProperties.add("id"); - } - if (!activitySourceFound) { - missingProperties.add("activitySource"); - } - - throw new IllegalStateException( - "Missing required property/properties: " + String.join(", ", missingProperties)); - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java index f7a2c52136f7..df3f41dd7349 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/KnowledgeSourceKind.java @@ -26,12 +26,6 @@ public final class KnowledgeSourceKind extends ExpandableStringEnum 0 ? searchableField.vectorSearchDimensions() : null; vectorSearchProfileName = CoreUtils.isNullOrEmpty(searchableField.vectorSearchProfileName()) @@ -325,12 +329,13 @@ private static SearchField enrichWithAnnotation(SearchField searchField, Member boolean hasAnalyzerName = !CoreUtils.isNullOrEmpty(analyzerName); boolean hasSearchAnalyzerName = !CoreUtils.isNullOrEmpty(searchAnalyzerName); boolean hasIndexAnalyzerName = !CoreUtils.isNullOrEmpty(indexAnalyzerName); + boolean hasNormalizerName = !CoreUtils.isNullOrEmpty(normalizerName); boolean hasVectorEncodingFormat = !CoreUtils.isNullOrEmpty(vectorEncodingFormat); if (searchable) { if (!isSearchableType) { errorMessage - .append("SearchField can only be used on 'Edm.String', 'Collection(Edm.String)', or " - + "'Collection(Edm.Single)' types. Property '") + .append("SearchField can only be used on 'Edm.String', 'Collection(Edm.String)', " + + "or 'Collection(Edm.Single)' types. Property '") .append(member.getName()) .append("' returns a '") .append(searchField.getType()) @@ -352,6 +357,13 @@ private static SearchField enrichWithAnnotation(SearchField searchField, Member "Please specify both vectorSearchDimensions and vectorSearchProfileName for Collection(Edm.Single) type. "); } + // Any field is allowed to have a normalizer, but it must be either a STRING or Collection(STRING) and have one + // of filterable, sortable, or facetable set to true. + if (hasNormalizerName && (!isStringOrCollectionString || !(filterable || sortable || facetable))) { + errorMessage.append("A field with a normalizer name can only be used on string properties and must have ") + .append("one of filterable, sortable, or facetable set to true. "); + } + if (errorMessage.length() > 0) { throw LOGGER.logExceptionAsError(new RuntimeException(errorMessage.toString())); } @@ -373,6 +385,10 @@ private static SearchField enrichWithAnnotation(SearchField searchField, Member searchField.setIndexAnalyzerName(LexicalAnalyzerName.fromString(indexAnalyzerName)); } + if (hasNormalizerName) { + searchField.setNormalizerName(LexicalNormalizerName.fromString(normalizerName)); + } + if (hasVectorEncodingFormat) { searchField.setVectorEncodingFormat(VectorEncodingFormat.fromString(vectorEncodingFormat)); } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/implementation/util/MappingUtils.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/implementation/util/MappingUtils.java index b99775a50e5a..5115bef5ae6a 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/implementation/util/MappingUtils.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/implementation/util/MappingUtils.java @@ -34,84 +34,50 @@ import java.util.Map; import java.util.function.Function; -import static java.util.stream.Collectors.toList; - public class MappingUtils { public static PagedResponse - mappingPagingDataSource(Response dataSourceResponse) { - List dataSourceMaps = dataSourceResponse.getValue().getDataSources(); - return new PagedResponseBase(dataSourceResponse.getRequest(), - dataSourceResponse.getStatusCode(), dataSourceResponse.getHeaders(), dataSourceMaps, null, null); + mapPagedDataSources(Response response) { + return pagedResponse(response, response.getValue().getDataSources()); } - public static PagedResponse - mappingPagingDataSourceNames(Response dataSourceResponse) { - List dataSourceNames = dataSourceResponse.getValue() - .getDataSources() - .stream() - .map(SearchIndexerDataSourceConnection::getName) - .collect(toList()); - return new PagedResponseBase(dataSourceResponse.getRequest(), - dataSourceResponse.getStatusCode(), dataSourceResponse.getHeaders(), dataSourceNames, null, null); + public static PagedResponse mapPagedDataSourceNames(Response response) { + return pagedResponse(response, + mapToNames(response.getValue().getDataSources(), SearchIndexerDataSourceConnection::getName)); } - public static PagedResponse mappingPagingSearchIndexNames(PagedResponse searchIndexResponse) { - List pageItems = new ArrayList<>(); - searchIndexResponse.getValue().forEach(item -> pageItems.add(item.getName())); - return new PagedResponseBase(searchIndexResponse.getRequest(), - searchIndexResponse.getStatusCode(), searchIndexResponse.getHeaders(), pageItems, - searchIndexResponse.getContinuationToken(), null); + public static PagedResponse mapPagedSearchIndexNames(PagedResponse response) { + return new PagedResponseBase(response.getRequest(), response.getStatusCode(), + response.getHeaders(), mapToNames(response.getValue(), SearchIndex::getName), + response.getContinuationToken(), null); } - public static PagedResponse - mappingPagingSearchIndexer(Response searchIndexerResponse) { - List searchIndexers = searchIndexerResponse.getValue().getIndexers(); - return new PagedResponseBase(searchIndexerResponse.getRequest(), - searchIndexerResponse.getStatusCode(), searchIndexerResponse.getHeaders(), searchIndexers, null, null); + public static PagedResponse mapPagedSearchIndexers(Response response) { + return pagedResponse(response, response.getValue().getIndexers()); } - public static PagedResponse - mappingPagingSearchIndexerNames(Response searchIndexerResponse) { - List searchIndexerNames - = searchIndexerResponse.getValue().getIndexers().stream().map(SearchIndexer::getName).collect(toList()); - return new PagedResponseBase(searchIndexerResponse.getRequest(), - searchIndexerResponse.getStatusCode(), searchIndexerResponse.getHeaders(), searchIndexerNames, null, null); + public static PagedResponse mapPagedSearchIndexerNames(Response response) { + return pagedResponse(response, mapToNames(response.getValue().getIndexers(), SearchIndexer::getName)); } - public static PagedResponse - mappingPagingSkillset(Response skillsetResponse) { - return new PagedResponseBase(skillsetResponse.getRequest(), - skillsetResponse.getStatusCode(), skillsetResponse.getHeaders(), skillsetResponse.getValue().getSkillsets(), - null, null); + public static PagedResponse mapPagedSkillsets(Response response) { + return pagedResponse(response, response.getValue().getSkillsets()); } - public static PagedResponse mappingPagingSkillsetNames(Response skillsetResponse) { - List skillsetNames - = skillsetResponse.getValue().getSkillsets().stream().map(SearchIndexerSkillset::getName).collect(toList()); - return new PagedResponseBase(skillsetResponse.getRequest(), - skillsetResponse.getStatusCode(), skillsetResponse.getHeaders(), skillsetNames, null, null); + public static PagedResponse mapPagedSkillsetNames(Response response) { + return pagedResponse(response, mapToNames(response.getValue().getSkillsets(), SearchIndexerSkillset::getName)); } - public static PagedResponse - mappingPagingSynonymMap(Response synonymMapResponse) { - return new PagedResponseBase(synonymMapResponse.getRequest(), - synonymMapResponse.getStatusCode(), synonymMapResponse.getHeaders(), - synonymMapResponse.getValue().getSynonymMaps(), null, null); + public static PagedResponse mapPagedSynonymMaps(Response response) { + return pagedResponse(response, response.getValue().getSynonymMaps()); } - public static PagedResponse - mappingPagingSynonymMapNames(Response synonymMapsResponse) { - List synonymMapNames - = synonymMapsResponse.getValue().getSynonymMaps().stream().map(SynonymMap::getName).collect(toList()); - return new PagedResponseBase(synonymMapsResponse.getRequest(), - synonymMapsResponse.getStatusCode(), synonymMapsResponse.getHeaders(), synonymMapNames, null, null); + public static PagedResponse mapPagedSynonymMapNames(Response response) { + return pagedResponse(response, mapToNames(response.getValue().getSynonymMaps(), SynonymMap::getName)); } - public static PagedResponse mappingTokenInfo(Response resultResponse) { - List tokenInfos = resultResponse.getValue().getTokens(); - return new PagedResponseBase(resultResponse.getRequest(), - resultResponse.getStatusCode(), resultResponse.getHeaders(), tokenInfos, null, null); + public static PagedResponse mapPagedTokenInfos(Response response) { + return pagedResponse(response, response.getValue().getTokens()); } public static Throwable exceptionMapper(Throwable throwable) { @@ -275,4 +241,13 @@ private static void setConfigurationValue(Object value, String key, Map PagedResponse pagedResponse(Response response, List values) { + return new PagedResponseBase(response.getRequest(), response.getStatusCode(), + response.getHeaders(), values, null, null); + } + + private static List mapToNames(List values, Function mapper) { + return values.stream().map(mapper).collect(() -> new ArrayList<>(values.size()), List::add, List::addAll); + } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java index 5ee1a9b43744..667c5b21f888 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java @@ -29,6 +29,7 @@ import com.azure.search.documents.indexes.models.IndexStatisticsSummary; import com.azure.search.documents.indexes.models.KnowledgeAgent; import com.azure.search.documents.indexes.models.KnowledgeSource; +import com.azure.search.documents.indexes.models.SearchAlias; import com.azure.search.documents.indexes.models.SearchField; import com.azure.search.documents.indexes.models.SearchIndex; import com.azure.search.documents.indexes.models.SearchIndexStatistics; @@ -667,7 +668,7 @@ public PagedFlux listIndexes() { public PagedFlux listIndexNames() { try { return new PagedFlux<>(() -> withContext(context -> this.listIndexesWithResponse("name", context)) - .map(MappingUtils::mappingPagingSearchIndexNames)); + .map(MappingUtils::mapPagedSearchIndexNames)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -855,7 +856,7 @@ private Mono> analyzeTextWithResponse(String in return restClient.getIndexes() .analyzeWithResponseAsync(indexName, AnalyzeRequestConverter.map(analyzeTextOptions), null, context) .onErrorMap(MappingUtils::exceptionMapper) - .map(MappingUtils::mappingTokenInfo); + .map(MappingUtils::mapPagedTokenInfos); } /** @@ -1002,7 +1003,7 @@ Mono> getSynonymMapWithResponse(String synonymMapName, Cont public PagedFlux listSynonymMaps() { try { return new PagedFlux<>(() -> withContext(context -> listSynonymMapsWithResponse(null, context)) - .map(MappingUtils::mappingPagingSynonymMap)); + .map(MappingUtils::mapPagedSynonymMaps)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -1028,7 +1029,7 @@ public PagedFlux listSynonymMaps() { public PagedFlux listSynonymMapNames() { try { return new PagedFlux<>(() -> withContext(context -> listSynonymMapsWithResponse("name", context)) - .map(MappingUtils::mappingPagingSynonymMapNames)); + .map(MappingUtils::mapPagedSynonymMapNames)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -1271,6 +1272,273 @@ PagedFlux getIndexStatsSummary(Context context) { } } + /** + * Creates a new Azure AI Search alias. + * + *

Code Sample

+ * + *

Create the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.createAlias(new SearchAlias("my-alias", Collections.singletonList("index-to-alias")))
+     *     .subscribe(searchAlias -> System.out.printf("Created alias '%s' that aliases index '%s'.",
+     *         searchAlias.getName(), searchAlias.getIndexes().get(0)));
+     * 
+ * + * + * @param alias definition of the alias to create. + * @return the created alias. + */ + public Mono createAlias(SearchAlias alias) { + return createAliasWithResponse(alias).flatMap(FluxUtil::toMono); + } + + /** + * Creates a new Azure AI Search alias. + * + *

Code Sample

+ * + *

Create the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.createAliasWithResponse(new SearchAlias("my-alias",
+     *         Collections.singletonList("index-to-alias")))
+     *     .subscribe(response ->
+     *         System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.",
+     *             response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)));
+     * 
+ * + * + * @param alias definition of the alias to create. + * @return the created alias. + */ + public Mono> createAliasWithResponse(SearchAlias alias) { + return withContext(context -> createAliasWithResponse(alias, context)); + } + + Mono> createAliasWithResponse(SearchAlias alias, Context context) { + try { + return restClient.getAliases().createWithResponseAsync(alias, null, context); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + + /** + * Creates or updates an Azure AI Search alias. + * + *

Code Sample

+ * + *

Create then update the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAlias(
+     *         new SearchAlias("my-alias", Collections.singletonList("index-to-alias")))
+     *     .flatMap(searchAlias -> {
+     *         System.out.printf("Created alias '%s' that aliases index '%s'.", searchAlias.getName(),
+     *             searchAlias.getIndexes().get(0));
+     *
+     *         return SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAlias(new SearchAlias(searchAlias.getName(),
+     *             Collections.singletonList("new-index-to-alias")));
+     *     }).subscribe(searchAlias -> System.out.printf("Updated alias '%s' to aliases index '%s'.",
+     *         searchAlias.getName(), searchAlias.getIndexes().get(0)));
+     * 
+ * + * + * @param alias definition of the alias to create or update. + * @return the created or updated alias. + */ + public Mono createOrUpdateAlias(SearchAlias alias) { + return createOrUpdateAliasWithResponse(alias, false).flatMap(FluxUtil::toMono); + } + + /** + * Creates or updates an Azure AI Search alias. + * + *

Code Sample

+ * + *

Create then update the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAliasWithResponse(
+     *         new SearchAlias("my-alias", Collections.singletonList("index-to-alias")), false)
+     *     .flatMap(response -> {
+     *         System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.",
+     *             response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0));
+     *
+     *         return SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAliasWithResponse(
+     *             new SearchAlias(response.getValue().getName(), Collections.singletonList("new-index-to-alias"))
+     *                 .setETag(response.getValue().getETag()), true);
+     *     }).subscribe(response ->
+     *         System.out.printf("Response status code %d. Updated alias '%s' that aliases index '%s'.",
+     *             response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)));
+     * 
+ * + * + * @param alias definition of the alias to create or update. + * @param onlyIfUnchanged only update the alias if the eTag matches the alias on the service + * @return the created or updated alias. + */ + public Mono> createOrUpdateAliasWithResponse(SearchAlias alias, boolean onlyIfUnchanged) { + if (alias == null) { + return monoError(LOGGER, new NullPointerException("'alias' cannot be null.")); + } + + return withContext(context -> createOrUpdateAliasWithResponse(alias, + onlyIfUnchanged ? alias.getETag() : null, context)); + } + + Mono> createOrUpdateAliasWithResponse(SearchAlias alias, String eTag, Context context) { + try { + return restClient.getAliases().createOrUpdateWithResponseAsync(alias.getName(), alias, eTag, null, null, + context); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + + /** + * Gets the Azure AI Search alias. + * + *

Code Sample

+ * + *

Get the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.getAlias("my-alias")
+     *     .subscribe(searchAlias -> System.out.printf("Retrieved alias '%s' that aliases index '%s'.",
+     *         searchAlias.getName(), searchAlias.getIndexes().get(0)));
+     * 
+ * + * + * @param aliasName name of the alias to get. + * @return the retrieved alias. + */ + public Mono getAlias(String aliasName) { + return getAliasWithResponse(aliasName).flatMap(FluxUtil::toMono); + } + + /** + * Gets the Azure AI Search alias. + * + *

Code Sample

+ * + *

Get the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.getAliasWithResponse("my-alias")
+     *     .subscribe(response ->
+     *         System.out.printf("Response status code %d. Retrieved alias '%s' that aliases index '%s'.",
+     *             response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)));
+     * 
+ * + * + * @param aliasName name of the alias to get. + * @return the retrieved alias. + */ + public Mono> getAliasWithResponse(String aliasName) { + return withContext(context -> getAliasWithResponse(aliasName, context)); + } + + Mono> getAliasWithResponse(String aliasName, Context context) { + try { + return restClient.getAliases().getWithResponseAsync(aliasName, null, context); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + + /** + * Deletes the Azure AI Search alias. + * + *

Code Sample

+ * + *

Delete the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.deleteAlias("my-alias")
+     *     .subscribe(ignored -> System.out.println("Deleted alias 'my-alias'."));
+     * 
+ * + * + * @param aliasName name of the alias to delete. + * @return a reactive response indicating deletion has completed. + */ + public Mono deleteAlias(String aliasName) { + return withContext(context -> deleteAliasWithResponse(aliasName, null, context)).flatMap(FluxUtil::toMono); + } + + /** + * Deletes the Azure AI Search alias. + * + *

Code Sample

+ * + *

Get the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.getAlias("my-alias")
+     *     .flatMap(searchAlias -> SEARCH_INDEX_ASYNC_CLIENT.deleteAliasWithResponse(searchAlias, true))
+     *     .subscribe(response -> System.out.printf("Response status code %d. Deleted alias 'my-alias'.",
+     *         response.getStatusCode()));
+     * 
+ * + * + * @param alias the alias to delete. + * @param onlyIfUnchanged only delete the alias if the eTag matches the alias on the service + * @return a reactive response indicating deletion has completed. + */ + public Mono> deleteAliasWithResponse(SearchAlias alias, boolean onlyIfUnchanged) { + if (alias == null) { + return monoError(LOGGER, new NullPointerException("'alias' cannot be null.")); + } + + return withContext(context -> deleteAliasWithResponse(alias.getName(), onlyIfUnchanged ? alias.getETag() : null, + context)); + } + + Mono> deleteAliasWithResponse(String aliasName, String eTag, Context context) { + try { + return restClient.getAliases().deleteWithResponseAsync(aliasName, eTag, null, null, context); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + + /** + * Lists all aliases in the Azure AI Search service. + * + *

Code Sample

+ * + *

List aliases

+ * + * + *
+     * SEARCH_INDEX_ASYNC_CLIENT.listAliases()
+     *     .doOnNext(searchAlias -> System.out.printf("Listed alias '%s' that aliases index '%s'.",
+     *         searchAlias.getName(), searchAlias.getIndexes().get(0)))
+     *     .subscribe();
+     * 
+ * + * + * @return a list of aliases in the service. + */ + public PagedFlux listAliases() { + try { + return new PagedFlux<>( + () -> withContext(context -> restClient.getAliases().listSinglePageAsync(null, context))); + } catch (RuntimeException ex) { + return pagedFluxError(LOGGER, ex); + } + } + /** * Creates a new agent. * diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java index 054ee0d255b7..78558d1fa3a7 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java @@ -29,6 +29,7 @@ import com.azure.search.documents.indexes.models.KnowledgeSource; import com.azure.search.documents.indexes.models.LexicalAnalyzerName; import com.azure.search.documents.indexes.models.LexicalTokenizerName; +import com.azure.search.documents.indexes.models.SearchAlias; import com.azure.search.documents.indexes.models.SearchField; import com.azure.search.documents.indexes.models.SearchIndex; import com.azure.search.documents.indexes.models.SearchIndexStatistics; @@ -692,7 +693,7 @@ public PagedIterable listIndexNames() { public PagedIterable listIndexNames(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingSearchIndexNames(this.listIndexesWithResponse("name", context))); + () -> MappingUtils.mapPagedSearchIndexNames(this.listIndexesWithResponse("name", context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -881,7 +882,7 @@ public PagedIterable analyzeText(String indexName, AnalyzeTex private PagedResponse analyzeTextWithResponse(String indexName, AnalyzeTextOptions analyzeTextOptions, Context context) { return Utility.executeRestCallWithExceptionHandling( - () -> MappingUtils.mappingTokenInfo(restClient.getIndexes() + () -> MappingUtils.mapPagedTokenInfos(restClient.getIndexes() .analyzeWithResponse(indexName, AnalyzeRequestConverter.map(analyzeTextOptions), null, context)), LOGGER); } @@ -1042,7 +1043,7 @@ public PagedIterable listSynonymMaps() { public PagedIterable listSynonymMaps(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingSynonymMap(listSynonymMapsWithResponse(null, context))); + () -> MappingUtils.mapPagedSynonymMaps(listSynonymMapsWithResponse(null, context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -1101,7 +1102,7 @@ public PagedIterable listSynonymMapNames() { public PagedIterable listSynonymMapNames(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingSynonymMapNames(listSynonymMapsWithResponse("name", context))); + () -> MappingUtils.mapPagedSynonymMapNames(listSynonymMapsWithResponse("name", context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -1313,6 +1314,273 @@ public static List buildSearchFields(Class model, FieldBuilderOp return SearchIndexAsyncClient.buildSearchFields(model, options); } + /** + * Creates a new Azure AI Search alias. + * + *

Code Sample

+ * + *

Create the search alias named "my-alias".

+ * + * + *
+     * SearchAlias searchAlias = SEARCH_INDEX_CLIENT.createAlias(new SearchAlias("my-alias",
+     *     Collections.singletonList("index-to-alias")));
+     * System.out.printf("Created alias '%s' that aliases index '%s'.", searchAlias.getName(),
+     *     searchAlias.getIndexes().get(0));
+     * 
+ * + * + * @param alias definition of the alias to create. + * @return the created alias. + */ + public SearchAlias createAlias(SearchAlias alias) { + return createAliasWithResponse(alias, Context.NONE).getValue(); + } + + /** + * Creates a new Azure AI Search alias. + * + *

Code Sample

+ * + *

Create the search alias named "my-alias".

+ * + * + *
+     * Response<SearchAlias> response = SEARCH_INDEX_CLIENT.createAliasWithResponse(new SearchAlias("my-alias",
+     *     Collections.singletonList("index-to-alias")), new Context(KEY_1, VALUE_1));
+     *
+     * System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.",
+     *     response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0));
+     * 
+ * + * + * @param alias definition of the alias to create. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return the created alias. + */ + public Response createAliasWithResponse(SearchAlias alias, Context context) { + try { + return restClient.getAliases().createWithResponse(alias, null, context); + } catch (RuntimeException ex) { + throw LOGGER.logExceptionAsError(ex); + } + } + + /** + * Creates or updates an Azure AI Search alias. + * + *

Code Sample

+ * + *

Create then update the search alias named "my-alias".

+ * + * + *
+     * SearchAlias searchAlias = SEARCH_INDEX_CLIENT.createOrUpdateAlias(
+     *     new SearchAlias("my-alias", Collections.singletonList("index-to-alias")));
+     *
+     * System.out.printf("Created alias '%s' that aliases index '%s'.", searchAlias.getName(),
+     *     searchAlias.getIndexes().get(0));
+     *
+     * searchAlias = SEARCH_INDEX_CLIENT.createOrUpdateAlias(new SearchAlias(searchAlias.getName(),
+     *     Collections.singletonList("new-index-to-alias")));
+     *
+     * System.out.printf("Updated alias '%s' to aliases index '%s'.", searchAlias.getName(),
+     *     searchAlias.getIndexes().get(0));
+     * 
+ * + * + * @param alias definition of the alias to create or update. + * @return the created or updated alias. + */ + public SearchAlias createOrUpdateAlias(SearchAlias alias) { + return createOrUpdateAliasWithResponse(alias, false, Context.NONE).getValue(); + } + + /** + * Creates or updates an Azure AI Search alias. + * + *

Code Sample

+ * + *

Create then update the search alias named "my-alias".

+ * + * + *
+     * Response<SearchAlias> response = SEARCH_INDEX_CLIENT.createOrUpdateAliasWithResponse(
+     *     new SearchAlias("my-alias", Collections.singletonList("index-to-alias")), false, new Context(KEY_1, VALUE_1));
+     *
+     * System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.",
+     *     response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0));
+     *
+     * response = SEARCH_INDEX_CLIENT.createOrUpdateAliasWithResponse(
+     *     new SearchAlias(response.getValue().getName(), Collections.singletonList("new-index-to-alias"))
+     *         .setETag(response.getValue().getETag()), true, new Context(KEY_1, VALUE_1));
+     *
+     * System.out.printf("Response status code %d. Updated alias '%s' that aliases index '%s'.",
+     *     response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0));
+     * 
+ * + * + * @param alias definition of the alias to create or update. + * @param onlyIfUnchanged only update the alias if the eTag matches the alias on the service. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return the created or updated alias. + */ + public Response createOrUpdateAliasWithResponse(SearchAlias alias, boolean onlyIfUnchanged, + Context context) { + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getAliases() + .createOrUpdateWithResponse(alias.getName(), alias, onlyIfUnchanged ? alias.getETag() : null, null, null, + context), LOGGER); + } + + /** + * Gets the Azure AI Search alias. + * + *

Code Sample

+ * + *

Get the search alias named "my-alias".

+ * + * + *
+     * SearchAlias searchAlias = SEARCH_INDEX_CLIENT.getAlias("my-alias");
+     *
+     * System.out.printf("Retrieved alias '%s' that aliases index '%s'.", searchAlias.getName(),
+     *     searchAlias.getIndexes().get(0));
+     * 
+ * + * + * @param aliasName name of the alias to get. + * @return the retrieved alias. + */ + public SearchAlias getAlias(String aliasName) { + return getAliasWithResponse(aliasName, Context.NONE).getValue(); + } + + /** + * Gets the Azure AI Search alias. + * + *

Code Sample

+ * + *

Get the search alias named "my-alias".

+ * + * + *
+     * Response<SearchAlias> response = SEARCH_INDEX_CLIENT.getAliasWithResponse("my-alias", new Context(KEY_1, VALUE_1));
+     *
+     * System.out.printf("Response status code %d. Retrieved alias '%s' that aliases index '%s'.",
+     *     response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0));
+     * 
+ * + * + * @param aliasName name of the alias to get. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return the retrieved alias. + */ + public Response getAliasWithResponse(String aliasName, Context context) { + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getAliases() + .getWithResponse(aliasName, null, context), LOGGER); + } + + /** + * Deletes the Azure AI Search alias. + * + *

Code Sample

+ * + *

Delete the search alias named "my-alias".

+ * + * + *
+     * SEARCH_INDEX_CLIENT.deleteAlias("my-alias");
+     *
+     * System.out.println("Deleted alias 'my-alias'.");
+     * 
+ * + * + * @param aliasName name of the alias to delete. + */ + public void deleteAlias(String aliasName) { + deleteAliasWithResponse(aliasName, null, Context.NONE); + } + + /** + * Deletes the Azure AI Search alias. + * + *

Code Sample

+ * + *

Delete the search alias named "my-alias".

+ * + * + *
+     * SearchAlias searchAlias = SEARCH_INDEX_CLIENT.getAlias("my-alias");
+     *
+     * Response<Void> response = SEARCH_INDEX_CLIENT.deleteAliasWithResponse(searchAlias, true,
+     *     new Context(KEY_1, VALUE_1));
+     *
+     * System.out.printf("Response status code %d. Deleted alias 'my-alias'.", response.getStatusCode());
+     * 
+ * + * + * @param alias the alias to delete. + * @param onlyIfUnchanged only delete the alias if the eTag matches the alias on the service. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return a response indicating the alias has been deleted. + */ + public Response deleteAliasWithResponse(SearchAlias alias, boolean onlyIfUnchanged, Context context) { + return deleteAliasWithResponse(alias.getName(), onlyIfUnchanged ? alias.getETag() : null, context); + } + + Response deleteAliasWithResponse(String aliasName, String eTag, Context context) { + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getAliases() + .deleteWithResponse(aliasName, eTag, null, null, context), LOGGER); + } + + /** + * Lists all aliases in the Azure AI Search service. + * + *

Code Sample

+ * + *

List aliases

+ * + * + *
+     * SEARCH_INDEX_CLIENT.listAliases()
+     *     .forEach(searchAlias -> System.out.printf("Listed alias '%s' that aliases index '%s'.",
+     *         searchAlias.getName(), searchAlias.getIndexes().get(0)));
+     * 
+ * + * + * @return a list of aliases in the service. + */ + public PagedIterable listAliases() { + return listAliases(Context.NONE); + } + + /** + * Lists all aliases in the Azure AI Search service. + * + *

Code Sample

+ * + *

List aliases

+ * + * + *
+     * SEARCH_INDEX_CLIENT.listAliases(new Context(KEY_1, VALUE_1))
+     *     .forEach(searchAlias -> System.out.printf("Listed alias '%s' that aliases index '%s'.",
+     *         searchAlias.getName(), searchAlias.getIndexes().get(0)));
+     * 
+ * + * + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return a list of aliases in the service. + */ + public PagedIterable listAliases(Context context) { + try { + return new PagedIterable<>(() -> restClient.getAliases() + .listSinglePage(null, context)); + } catch (RuntimeException ex) { + throw LOGGER.logExceptionAsError(ex); + } + } + /** * Creates a new agent. * diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java index bc220d94b90e..8032322e09ba 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java @@ -15,10 +15,15 @@ import com.azure.search.documents.SearchServiceVersion; import com.azure.search.documents.implementation.util.MappingUtils; import com.azure.search.documents.indexes.implementation.SearchServiceClientImpl; +import com.azure.search.documents.indexes.implementation.models.DocumentKeysOrIds; import com.azure.search.documents.indexes.implementation.models.ErrorResponseException; import com.azure.search.documents.indexes.implementation.models.ListDataSourcesResult; import com.azure.search.documents.indexes.implementation.models.ListIndexersResult; import com.azure.search.documents.indexes.implementation.models.ListSkillsetsResult; +import com.azure.search.documents.indexes.implementation.models.SkillNames; +import com.azure.search.documents.indexes.models.CreateOrUpdateDataSourceConnectionOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateIndexerOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateSkillsetOptions; import com.azure.search.documents.indexes.models.IndexerResyncBody; import com.azure.search.documents.indexes.models.SearchIndexer; import com.azure.search.documents.indexes.models.SearchIndexerDataSourceConnection; @@ -26,6 +31,7 @@ import com.azure.search.documents.indexes.models.SearchIndexerStatus; import reactor.core.publisher.Mono; +import java.util.List; import java.util.function.Function; import static com.azure.core.util.FluxUtil.monoError; @@ -499,6 +505,50 @@ public Mono> createOrUpdateDataSourc context -> createOrUpdateDataSourceConnectionWithResponse(dataSource, onlyIfUnchanged, null, context)); } + /** + * Creates a new Azure AI Search data source or updates a data source if it already exists. + * + *

Code Sample

+ * + *

Create or update search indexer data source connection named "dataSource".

+ * + * + *
+     * SEARCH_INDEXER_ASYNC_CLIENT.getDataSourceConnection("dataSource")
+     *     .flatMap(dataSource -> {
+     *         dataSource.setContainer(new SearchIndexerDataContainer("updatecontainer"));
+     *         return SEARCH_INDEXER_ASYNC_CLIENT.createOrUpdateDataSourceConnectionWithResponse(
+     *             new CreateOrUpdateDataSourceConnectionOptions(dataSource)
+     *                 .setOnlyIfUnchanged(true)
+     *                 .setCacheResetRequirementsIgnored(true));
+     *     })
+     *     .subscribe(updateDataSource ->
+     *         System.out.printf("The status code of the response is %s.%nThe dataSource name is %s. "
+     *                 + "The container name of dataSource is %s.%n", updateDataSource.getStatusCode(),
+     *             updateDataSource.getValue().getName(), updateDataSource.getValue().getContainer().getName()));
+     * 
+ * + * + * @param options The options used to create or update the + * {@link SearchIndexerDataSourceConnection data source connection}. + * @return a data source response. + * @throws NullPointerException If {@code options} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createOrUpdateDataSourceConnectionWithResponse( + CreateOrUpdateDataSourceConnectionOptions options) { + if (options == null) { + return monoError(LOGGER, new NullPointerException("'options' cannot be null.")); + } + + return withContext(context -> createOrUpdateDataSourceConnectionWithResponse(options.getDataSourceConnection(), + options.isOnlyIfUnchanged(), options.isCacheResetRequirementsIgnored(), context)); + } + Mono> createOrUpdateDataSourceConnectionWithResponse( SearchIndexerDataSourceConnection dataSource, boolean onlyIfUnchanged, Boolean ignoreResetRequirements, Context context) { @@ -680,7 +730,7 @@ public PagedFlux listDataSourceConnections() try { return new PagedFlux<>( () -> withContext(context -> this.listDataSourceConnectionsWithResponse(null, context)) - .map(MappingUtils::mappingPagingDataSource)); + .map(MappingUtils::mapPagedDataSources)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -707,7 +757,7 @@ public PagedFlux listDataSourceConnectionNames() { try { return new PagedFlux<>( () -> withContext(context -> this.listDataSourceConnectionsWithResponse("name", context)) - .map(MappingUtils::mappingPagingDataSourceNames)); + .map(MappingUtils::mapPagedDataSourceNames)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -920,6 +970,53 @@ public Mono> createOrUpdateIndexerWithResponse(SearchInd return withContext(context -> createOrUpdateIndexerWithResponse(indexer, onlyIfUnchanged, null, null, context)); } + /** + * Creates a new Azure AI Search indexer or updates an indexer if it already exists. + * + *

Code Sample

+ * + *

Create or update search indexer named "searchIndexer".

+ * + * + *
+     * SEARCH_INDEXER_ASYNC_CLIENT.getIndexer("searchIndexer")
+     *     .flatMap(searchIndexerFromService -> {
+     *         searchIndexerFromService.setFieldMappings(Collections.singletonList(
+     *             new FieldMapping("hotelName").setTargetFieldName("HotelName")));
+     *         return SEARCH_INDEXER_ASYNC_CLIENT.createOrUpdateIndexerWithResponse(
+     *             new CreateOrUpdateIndexerOptions(searchIndexerFromService)
+     *                 .setOnlyIfUnchanged(true)
+     *                 .setCacheReprocessingChangeDetectionDisabled(false)
+     *                 .setCacheResetRequirementsIgnored(true));
+     *     })
+     *     .subscribe(indexerFromService ->
+     *         System.out.printf("The status code of the response is %s.%nThe indexer name is %s. "
+     *                 + "The target field name of indexer is %s.%n", indexerFromService.getStatusCode(),
+     *             indexerFromService.getValue().getName(),
+     *             indexerFromService.getValue().getFieldMappings().get(0).getTargetFieldName()));
+     * 
+ * + * + * @param options The options used to create or update the {@link SearchIndexer indexer}. + * @return a response containing the created Indexer. + * @throws NullPointerException If {@code options} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createOrUpdateIndexerWithResponse(CreateOrUpdateIndexerOptions options) { + if (options == null) { + return monoError(LOGGER, new NullPointerException("'options' cannot be null.")); + } + + return withContext( + context -> createOrUpdateIndexerWithResponse(options.getIndexer(), options.isOnlyIfUnchanged(), + options.isCacheReprocessingChangeDetectionDisabled(), options.isCacheResetRequirementsIgnored(), + context)); + } + Mono> createOrUpdateIndexerWithResponse(SearchIndexer indexer, boolean onlyIfUnchanged, Boolean disableCacheReprocessingChangeDetection, Boolean ignoreResetRequirements, Context context) { if (indexer == null) { @@ -1016,7 +1113,7 @@ Mono> getIndexerWithResponse(String indexerName, Context public PagedFlux listIndexers() { try { return new PagedFlux<>(() -> withContext(context -> this.listIndexersWithResponse(null, context)) - .map(MappingUtils::mappingPagingSearchIndexer)); + .map(MappingUtils::mapPagedSearchIndexers)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -1042,7 +1139,7 @@ public PagedFlux listIndexers() { public PagedFlux listIndexerNames() { try { return new PagedFlux<>(() -> withContext(context -> this.listIndexersWithResponse("name", context)) - .map(MappingUtils::mappingPagingSearchIndexerNames)); + .map(MappingUtils::mapPagedSearchIndexerNames)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -1298,6 +1395,93 @@ Mono> getIndexerStatusWithResponse(String indexerN } } + /** + * Resets specific documents in the datasource to be selectively re-ingested by the indexer. + * + * + *
+     * // Reset the documents with keys 1234 and 4321.
+     * SEARCH_INDEXER_ASYNC_CLIENT.resetDocuments("searchIndexer", false, Arrays.asList("1234", "4321"), null)
+     *     // Clear the previous documents to be reset and replace them with documents 1235 and 5231.
+     *     .then(SEARCH_INDEXER_ASYNC_CLIENT.resetDocuments("searchIndexer", true, Arrays.asList("1235", "5321"), null))
+     *     .subscribe();
+     * 
+ * + * + * @param indexerName The name of the indexer to reset documents for. + * @param overwrite If false, keys or IDs will be appended to existing ones. If true, only the keys or IDs in this + * payload will be queued to be re-ingested. + * @param documentKeys Document keys to be reset. + * @param datasourceDocumentIds Datasource document identifiers to be reset. + * @return A response signalling completion. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono resetDocuments(String indexerName, Boolean overwrite, List documentKeys, + List datasourceDocumentIds) { + return withContext( + context -> resetDocumentsWithResponse(indexerName, overwrite, documentKeys, datasourceDocumentIds, context)) + .map(Response::getValue); + } + + /** + * Resets specific documents in the datasource to be selectively re-ingested by the indexer. + * + * + *
+     * SEARCH_INDEXER_ASYNC_CLIENT.getIndexer("searchIndexer")
+     *     .flatMap(searchIndexer -> SEARCH_INDEXER_ASYNC_CLIENT.resetDocumentsWithResponse(searchIndexer, false,
+     *         Arrays.asList("1234", "4321"), null)
+     *         .flatMap(resetDocsResult -> {
+     *             System.out.printf("Requesting documents to be reset completed with status code %d.%n",
+     *                 resetDocsResult.getStatusCode());
+     *
+     *             // Clear the previous documents to be reset and replace them with documents 1235 and 5231.
+     *             return SEARCH_INDEXER_ASYNC_CLIENT.resetDocumentsWithResponse(searchIndexer, true,
+     *                 Arrays.asList("1235", "5321"), null);
+     *         }))
+     *     .subscribe(resetDocsResult ->
+     *         System.out.printf("Overwriting the documents to be reset completed with status code %d.%n",
+     *             resetDocsResult.getStatusCode()));
+     * 
+ * + * + * @param indexer The indexer to reset documents for. + * @param overwrite If false, keys or IDs will be appended to existing ones. If true, only the keys or IDs in this + * payload will be queued to be re-ingested. + * @param documentKeys Document keys to be reset. + * @param datasourceDocumentIds Datasource document identifiers to be reset. + * @return A response signalling completion. + * @throws NullPointerException If {@code indexer} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> resetDocumentsWithResponse(SearchIndexer indexer, Boolean overwrite, + List documentKeys, List datasourceDocumentIds) { + if (indexer == null) { + return monoError(LOGGER, new NullPointerException("'indexer' cannot be null.")); + } + + return withContext(context -> + resetDocumentsWithResponse(indexer.getName(), overwrite, documentKeys, datasourceDocumentIds, context)); + } + + Mono> resetDocumentsWithResponse(String indexerName, Boolean overwrite, List documentKeys, + List datasourceDocumentIds, Context context) { + try { + DocumentKeysOrIds documentKeysOrIds = new DocumentKeysOrIds().setDocumentKeys(documentKeys) + .setDatasourceDocumentIds(datasourceDocumentIds); + + return restClient.getIndexers() + .resetDocsWithResponseAsync(indexerName, overwrite, documentKeysOrIds, null, context); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + } + } + /** * Creates a new skillset in an Azure AI Search service. * @@ -1478,7 +1662,7 @@ Mono> getSkillsetWithResponse(String skillsetNam public PagedFlux listSkillsets() { try { return new PagedFlux<>(() -> withContext(context -> listSkillsetsWithResponse(null, context)) - .map(MappingUtils::mappingPagingSkillset)); + .map(MappingUtils::mapPagedSkillsets)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -1504,7 +1688,7 @@ public PagedFlux listSkillsets() { public PagedFlux listSkillsetNames() { try { return new PagedFlux<>(() -> withContext(context -> listSkillsetsWithResponse("name", context)) - .map(MappingUtils::mappingPagingSkillsetNames)); + .map(MappingUtils::mapPagedSkillsetNames)); } catch (RuntimeException ex) { return pagedFluxError(LOGGER, ex); } @@ -1585,6 +1769,53 @@ public Mono> createOrUpdateSkillsetWithResponse( context -> createOrUpdateSkillsetWithResponse(skillset, onlyIfUnchanged, null, null, context)); } + /** + * Creates a new Azure AI Search skillset or updates a skillset if it already exists. + * + *

Code Sample

+ * + *

Create or update search indexer skillset "searchIndexerSkillset".

+ * + * + *
+     * SEARCH_INDEXER_ASYNC_CLIENT.getSkillset("searchIndexerSkillset")
+     *     .flatMap(indexerSkillset -> {
+     *         indexerSkillset.setDescription("This is new description!");
+     *         return SEARCH_INDEXER_ASYNC_CLIENT.createOrUpdateSkillsetWithResponse(
+     *             new CreateOrUpdateSkillsetOptions(indexerSkillset)
+     *                 .setOnlyIfUnchanged(true)
+     *                 .setCacheReprocessingChangeDetectionDisabled(false)
+     *                 .setCacheResetRequirementsIgnored(true));
+     *     })
+     *     .subscribe(updateSkillsetResponse ->
+     *         System.out.printf("The status code of the response is %s.%nThe indexer skillset name is %s. "
+     *             + "The description of indexer skillset is %s.%n", updateSkillsetResponse.getStatusCode(),
+     *             updateSkillsetResponse.getValue().getName(),
+     *             updateSkillsetResponse.getValue().getDescription()));
+     * 
+ * + * + * @param options The options used to create or update the {@link SearchIndexerSkillset skillset}. + * @return a response containing the skillset that was created or updated. + * @throws NullPointerException If {@code options} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> createOrUpdateSkillsetWithResponse( + CreateOrUpdateSkillsetOptions options) { + if (options == null) { + return monoError(LOGGER, new NullPointerException("'options' cannot be null.")); + } + + return withContext( + context -> createOrUpdateSkillsetWithResponse(options.getSkillset(), options.isOnlyIfUnchanged(), + options.isCacheReprocessingChangeDetectionDisabled(), + options.isCacheResetRequirementsIgnored(), context)); + } + Mono> createOrUpdateSkillsetWithResponse(SearchIndexerSkillset skillset, boolean onlyIfUnchanged, Boolean disableCacheReprocessingChangeDetection, Boolean ignoreResetRequirements, Context context) { @@ -1711,4 +1942,65 @@ Mono> resyncWithResponseAsync(String indexerName, IndexerResyncBo return monoError(LOGGER, ex); } } + + /** + * Resets skills in an existing skillset in an Azure AI Search service. + * + * + *
+     * // Reset the "myOcr" and "myText" skills.
+     * SEARCH_INDEXER_ASYNC_CLIENT.resetSkills("searchIndexerSkillset", Arrays.asList("myOcr", "myText"))
+     *     .subscribe();
+     * 
+ * + * + * @param skillsetName The name of the skillset to reset. + * @param skillNames The skills to reset. + * @return A response signalling completion. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono resetSkills(String skillsetName, List skillNames) { + return withContext(context -> resetSkillsWithResponse(skillsetName, skillNames, context).flatMap(FluxUtil::toMono)); + } + + /** + * Resets skills in an existing skillset in an Azure AI Search service. + * + * + *
+     * SEARCH_INDEXER_ASYNC_CLIENT.getSkillset("searchIndexerSkillset")
+     *     .flatMap(searchIndexerSkillset -> SEARCH_INDEXER_ASYNC_CLIENT.resetSkillsWithResponse(searchIndexerSkillset,
+     *         Arrays.asList("myOcr", "myText")))
+     *     .subscribe(resetSkillsResponse -> System.out.printf("Resetting skills completed with status code %d.%n",
+     *         resetSkillsResponse.getStatusCode()));
+     * 
+ * + * + * @param skillset The skillset to reset. + * @param skillNames The skills to reset. + * @return A response signalling completion. + * @throws NullPointerException If {@code skillset} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> resetSkillsWithResponse(SearchIndexerSkillset skillset, List skillNames) { + if (skillset == null) { + return monoError(LOGGER, new NullPointerException("'skillset' cannot be null.")); + } + + return withContext(context -> resetSkillsWithResponse(skillset.getName(), skillNames, context)); + } + + Mono> resetSkillsWithResponse(String skillsetName, List skillNames, Context context) { + try { + return restClient.getSkillsets() + .resetSkillsWithResponseAsync(skillsetName, new SkillNames().setSkillNames(skillNames), null, context); + } catch (RuntimeException ex) { + return monoError(LOGGER, ex); + + } + } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java index d09d25b3f7a2..4f406f3393a7 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java @@ -15,16 +15,24 @@ import com.azure.search.documents.implementation.util.MappingUtils; import com.azure.search.documents.implementation.util.Utility; import com.azure.search.documents.indexes.implementation.SearchServiceClientImpl; +import com.azure.search.documents.indexes.implementation.models.DocumentKeysOrIds; import com.azure.search.documents.indexes.implementation.models.ErrorResponseException; import com.azure.search.documents.indexes.implementation.models.ListDataSourcesResult; import com.azure.search.documents.indexes.implementation.models.ListIndexersResult; import com.azure.search.documents.indexes.implementation.models.ListSkillsetsResult; +import com.azure.search.documents.indexes.implementation.models.SkillNames; +import com.azure.search.documents.indexes.models.CreateOrUpdateDataSourceConnectionOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateIndexerOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateSkillsetOptions; import com.azure.search.documents.indexes.models.IndexerResyncBody; import com.azure.search.documents.indexes.models.SearchIndexer; import com.azure.search.documents.indexes.models.SearchIndexerDataSourceConnection; import com.azure.search.documents.indexes.models.SearchIndexerSkillset; import com.azure.search.documents.indexes.models.SearchIndexerStatus; +import java.util.List; +import java.util.Objects; + /** * This class provides a client that contains the operations for creating, getting, listing, updating, or deleting data * source connections, indexers, or skillsets and running or resetting indexers in an Azure AI Search service. @@ -465,6 +473,44 @@ public Response createOrUpdateDataSourceConne return createOrUpdateDataSourceConnectionWithResponse(dataSourceConnection, onlyIfUnchanged, null, context); } + /** + * Creates a new Azure AI Search data source or updates a data source if it already exists. + * + *

Code Sample

+ * + *

Create or update search indexer data source connection named "dataSource".

+ * + * + *
+     * SearchIndexerDataSourceConnection dataSource = SEARCH_INDEXER_CLIENT.getDataSourceConnection("dataSource");
+     * dataSource.setContainer(new SearchIndexerDataContainer("updatecontainer"));
+     * CreateOrUpdateDataSourceConnectionOptions options = new CreateOrUpdateDataSourceConnectionOptions(dataSource)
+     *     .setOnlyIfUnchanged(true)
+     *     .setCacheResetRequirementsIgnored(true);
+     *
+     * Response<SearchIndexerDataSourceConnection> updateDataSource = SEARCH_INDEXER_CLIENT
+     *     .createOrUpdateDataSourceConnectionWithResponse(options, new Context(KEY_1, VALUE_1));
+     * System.out.printf("The status code of the response is %s.%nThe dataSource name is %s. "
+     *         + "The container name of dataSource is %s.%n", updateDataSource.getStatusCode(),
+     *     updateDataSource.getValue().getName(), updateDataSource.getValue().getContainer().getName());
+     * 
+ * + * + * @param options The options used to create or update the {@link SearchIndexerDataSourceConnection data source + * connection}. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return a data source response. + * @throws NullPointerException If {@code options} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response createOrUpdateDataSourceConnectionWithResponse( + CreateOrUpdateDataSourceConnectionOptions options, Context context) { + Objects.requireNonNull(options, "'options' cannot be null."); + + return createOrUpdateDataSourceConnectionWithResponse(options.getDataSourceConnection(), + options.isOnlyIfUnchanged(), options.isCacheResetRequirementsIgnored(), context); + } + Response createOrUpdateDataSourceConnectionWithResponse( SearchIndexerDataSourceConnection dataSource, boolean onlyIfUnchanged, Boolean ignoreResetRequirements, Context context) { @@ -645,7 +691,7 @@ public PagedIterable listDataSourceConnection public PagedIterable listDataSourceConnections(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingDataSource(listDataSourceConnectionsWithResponse(null, context))); + () -> MappingUtils.mapPagedDataSources(listDataSourceConnectionsWithResponse(null, context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -704,7 +750,7 @@ public PagedIterable listDataSourceConnectionNames() { public PagedIterable listDataSourceConnectionNames(Context context) { try { return new PagedIterable<>(() -> MappingUtils - .mappingPagingDataSourceNames(this.listDataSourceConnectionsWithResponse("name", context))); + .mapPagedDataSourceNames(this.listDataSourceConnectionsWithResponse("name", context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -875,6 +921,44 @@ public Response createOrUpdateIndexerWithResponse(SearchIndexer i return createOrUpdateIndexerWithResponse(indexer, onlyIfUnchanged, null, null, context); } + /** + * Creates a new Azure AI Search indexer or updates an indexer if it already exists. + * + *

Code Sample

+ * + *

Create or update search indexer named "searchIndexer".

+ * + * + *
+     * SearchIndexer searchIndexerFromService = SEARCH_INDEXER_CLIENT.getIndexer("searchIndexer");
+     * searchIndexerFromService.setFieldMappings(Collections.singletonList(
+     *     new FieldMapping("hotelName").setTargetFieldName("HotelName")));
+     * CreateOrUpdateIndexerOptions options = new CreateOrUpdateIndexerOptions(searchIndexerFromService)
+     *     .setOnlyIfUnchanged(true)
+     *     .setCacheReprocessingChangeDetectionDisabled(false)
+     *     .setCacheResetRequirementsIgnored(true);
+     * Response<SearchIndexer> indexerFromService = SEARCH_INDEXER_CLIENT.createOrUpdateIndexerWithResponse(
+     *     options, new Context(KEY_1, VALUE_1));
+     * System.out.printf("The status code of the response is %s.%nThe indexer name is %s. "
+     *         + "The target field name of indexer is %s.%n", indexerFromService.getStatusCode(),
+     *     indexerFromService.getValue().getName(),
+     *     indexerFromService.getValue().getFieldMappings().get(0).getTargetFieldName());
+     * 
+ * + * + * @param options The options used to create or update the {@link SearchIndexer indexer}. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return A response object containing the Indexer. + * @throws NullPointerException If {@code options} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response createOrUpdateIndexerWithResponse(CreateOrUpdateIndexerOptions options, + Context context) { + Objects.requireNonNull(options, "'options' cannot be null."); + return createOrUpdateIndexerWithResponse(options.getIndexer(), options.isOnlyIfUnchanged(), + options.isCacheReprocessingChangeDetectionDisabled(), options.isCacheResetRequirementsIgnored(), context); + } + Response createOrUpdateIndexerWithResponse(SearchIndexer indexer, boolean onlyIfUnchanged, Boolean disableCacheReprocessingChangeDetection, Boolean ignoreResetRequirements, Context context) { if (indexer == null) { @@ -938,7 +1022,7 @@ public PagedIterable listIndexers() { public PagedIterable listIndexers(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingSearchIndexer(listIndexersWithResponse(null, context))); + () -> MappingUtils.mapPagedSearchIndexers(listIndexersWithResponse(null, context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -997,7 +1081,7 @@ public PagedIterable listIndexerNames() { public PagedIterable listIndexerNames(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingSearchIndexerNames(this.listIndexersWithResponse("name", context))); + () -> MappingUtils.mapPagedSearchIndexerNames(this.listIndexersWithResponse("name", context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -1431,7 +1515,7 @@ public PagedIterable listSkillsets() { public PagedIterable listSkillsets(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingSkillset(listSkillsetsWithResponse(null, context))); + () -> MappingUtils.mapPagedSkillsets(listSkillsetsWithResponse(null, context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -1490,7 +1574,7 @@ public PagedIterable listSkillsetNames() { public PagedIterable listSkillsetNames(Context context) { try { return new PagedIterable<>( - () -> MappingUtils.mappingPagingSkillsetNames(listSkillsetsWithResponse("name", context))); + () -> MappingUtils.mapPagedSkillsetNames(listSkillsetsWithResponse("name", context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -1553,6 +1637,43 @@ public Response createOrUpdateSkillsetWithResponse(Search return createOrUpdateSkillsetWithResponse(skillset, onlyIfUnchanged, null, null, context); } + /** + * Creates a new Azure AI Search skillset or updates a skillset if it already exists. + * + *

Code Sample

+ * + *

Create or update search indexer skillset "searchIndexerSkillset".

+ * + * + *
+     * SearchIndexerSkillset indexerSkillset = SEARCH_INDEXER_CLIENT.getSkillset("searchIndexerSkillset");
+     * indexerSkillset.setDescription("This is new description!");
+     * CreateOrUpdateSkillsetOptions options = new CreateOrUpdateSkillsetOptions(indexerSkillset)
+     *     .setOnlyIfUnchanged(true)
+     *     .setCacheReprocessingChangeDetectionDisabled(false)
+     *     .setCacheResetRequirementsIgnored(true);
+     * Response<SearchIndexerSkillset> updateSkillsetResponse = SEARCH_INDEXER_CLIENT.createOrUpdateSkillsetWithResponse(
+     *     options, new Context(KEY_1, VALUE_1));
+     * System.out.printf("The status code of the response is %s.%nThe indexer skillset name is %s. "
+     *         + "The description of indexer skillset is %s.%n", updateSkillsetResponse.getStatusCode(),
+     *     updateSkillsetResponse.getValue().getName(),
+     *     updateSkillsetResponse.getValue().getDescription());
+     * 
+ * + * + * @param options The options used to create or update the {@link SearchIndexerSkillset skillset}. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return a response containing the skillset that was created or updated. + * @throws NullPointerException If {@code options} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response createOrUpdateSkillsetWithResponse(CreateOrUpdateSkillsetOptions options, + Context context) { + Objects.requireNonNull(options, "'options' cannot be null."); + return createOrUpdateSkillsetWithResponse(options.getSkillset(), options.isOnlyIfUnchanged(), + options.isCacheReprocessingChangeDetectionDisabled(), options.isCacheResetRequirementsIgnored(), context); + } + Response createOrUpdateSkillsetWithResponse(SearchIndexerSkillset skillset, boolean onlyIfUnchanged, Boolean disableCacheReprocessingChangeDetection, Boolean ignoreResetRequirements, Context context) { @@ -1647,4 +1768,116 @@ public Response resyncWithResponse(String indexerName, IndexerResyncBody i () -> restClient.getIndexers().resyncWithResponse(indexerName, indexerResync, null, context), LOGGER); } + /** + * Resets specific documents in the datasource to be selectively re-ingested by the indexer. + * + * + *
+     * // Reset the documents with keys 1234 and 4321.
+     * SEARCH_INDEXER_CLIENT.resetDocuments("searchIndexer", false, Arrays.asList("1234", "4321"), null);
+     *
+     * // Clear the previous documents to be reset and replace them with documents 1235 and 5231.
+     * SEARCH_INDEXER_CLIENT.resetDocuments("searchIndexer", true, Arrays.asList("1235", "5321"), null);
+     * 
+ * + * + * @param indexerName The name of the indexer to reset documents for. + * @param overwrite If false, keys or IDs will be appended to existing ones. If true, only the keys or IDs in this + * payload will be queued to be re-ingested. + * @param documentKeys Document keys to be reset. + * @param datasourceDocumentIds Datasource document identifiers to be reset. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public void resetDocuments(String indexerName, Boolean overwrite, List documentKeys, + List datasourceDocumentIds) { + resetDocumentsWithResponse(new SearchIndexer(indexerName), overwrite, documentKeys, datasourceDocumentIds, + Context.NONE); + } + + /** + * Resets specific documents in the datasource to be selectively re-ingested by the indexer. + * + * + *
+     * SearchIndexer searchIndexer = SEARCH_INDEXER_CLIENT.getIndexer("searchIndexer");
+     *
+     * // Reset the documents with keys 1234 and 4321.
+     * Response<Void> resetDocsResult = SEARCH_INDEXER_CLIENT.resetDocumentsWithResponse(searchIndexer, false,
+     *     Arrays.asList("1234", "4321"), null, new Context(KEY_1, VALUE_1));
+     * System.out.printf("Requesting documents to be reset completed with status code %d.%n",
+     *     resetDocsResult.getStatusCode());
+     *
+     * // Clear the previous documents to be reset and replace them with documents 1235 and 5231.
+     * resetDocsResult = SEARCH_INDEXER_CLIENT.resetDocumentsWithResponse(searchIndexer, true,
+     *     Arrays.asList("1235", "5321"), null, new Context(KEY_1, VALUE_1));
+     * System.out.printf("Overwriting the documents to be reset completed with status code %d.%n",
+     *     resetDocsResult.getStatusCode());
+     * 
+ * + * + * @param indexer The indexer to reset documents for. + * @param overwrite If false, keys or IDs will be appended to existing ones. If true, only the keys or IDs in this + * payload will be queued to be re-ingested. + * @param documentKeys Document keys to be reset. + * @param datasourceDocumentIds Datasource document identifiers to be reset. + * @param context additional context that is passed through the HTTP pipeline during the service call + * @return A response signalling completion. + * @throws NullPointerException If {@code indexer} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response resetDocumentsWithResponse(SearchIndexer indexer, Boolean overwrite, + List documentKeys, List datasourceDocumentIds, Context context) { + DocumentKeysOrIds documentKeysOrIds = new DocumentKeysOrIds() + .setDocumentKeys(documentKeys) + .setDatasourceDocumentIds(datasourceDocumentIds); + + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getIndexers().resetDocsWithResponse( + indexer.getName(), overwrite, documentKeysOrIds, null, context), LOGGER); + } + + /** + * Resets skills in an existing skillset in an Azure AI Search service. + * + * + *
+     * // Reset the "myOcr" and "myText" skills.
+     * SEARCH_INDEXER_CLIENT.resetSkills("searchIndexerSkillset", Arrays.asList("myOcr", "myText"));
+     * 
+ * + * + * @param skillsetName The name of the skillset to reset. + * @param skillNames The skills to reset. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public void resetSkills(String skillsetName, List skillNames) { + resetSkillsWithResponse(new SearchIndexerSkillset(skillsetName), skillNames, Context.NONE); + } + + /** + * Resets skills in an existing skillset in an Azure AI Search service. + * + * + *
+     * SearchIndexerSkillset searchIndexerSkillset = SEARCH_INDEXER_CLIENT.getSkillset("searchIndexerSkillset");
+     *
+     * // Reset the "myOcr" and "myText" skills.
+     * Response<Void> resetSkillsResponse = SEARCH_INDEXER_CLIENT.resetSkillsWithResponse(searchIndexerSkillset,
+     *     Arrays.asList("myOcr", "myText"), new Context(KEY_1, VALUE_1));
+     * System.out.printf("Resetting skills completed with status code %d.%n", resetSkillsResponse.getStatusCode());
+     * 
+ * + * + * @param skillset The skillset to reset. + * @param skillNames The skills to reset. + * @param context Additional context that is passed through the HTTP pipeline during the service call. + * @return A response signalling completion. + * @throws NullPointerException If {@code skillset} is null. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response resetSkillsWithResponse(SearchIndexerSkillset skillset, List skillNames, + Context context) { + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getSkillsets() + .resetSkillsWithResponse(skillset.getName(), new SkillNames().setSkillNames(skillNames), null, + context), LOGGER); + } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java index e7ed82927c88..0bbd8b006b66 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java @@ -5,6 +5,7 @@ import com.azure.search.documents.indexes.models.FieldBuilderOptions; import com.azure.search.documents.indexes.models.LexicalAnalyzerName; +import com.azure.search.documents.indexes.models.LexicalNormalizerName; import com.azure.search.documents.indexes.models.SearchField; import com.azure.search.documents.indexes.models.SynonymMap; import com.azure.search.documents.indexes.models.VectorEncodingFormat; @@ -94,6 +95,14 @@ */ String indexAnalyzerName() default ""; + /** + * A {@link LexicalNormalizerName} to associate as the normalizer for the {@link SearchField field}. + * + * @return The {@link LexicalNormalizerName} that will be associated as the normalizer for the + * {@link SearchField field}. + */ + String normalizerName() default ""; + /** * A list of {@link SynonymMap} names to be associated with the {@link SearchField field}. *

diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java index 25779193e291..4c67d8e6b85c 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java @@ -4,6 +4,7 @@ package com.azure.search.documents.indexes; import com.azure.search.documents.indexes.models.FieldBuilderOptions; +import com.azure.search.documents.indexes.models.LexicalNormalizerName; import com.azure.search.documents.indexes.models.SearchField; import java.lang.annotation.ElementType; @@ -53,6 +54,14 @@ */ boolean isFilterable() default false; + /** + * A {@link LexicalNormalizerName} to associate as the normalizer for the {@link SearchField field}. + * + * @return The {@link LexicalNormalizerName} that will be associated as the normalizer for the + * {@link SearchField field}. + */ + String normalizerName() default ""; + /** * A value indicating whether the field should be used as a permission filter. * diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java new file mode 100644 index 000000000000..2567800a93f2 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.search.documents.indexes.models; + +import java.util.Objects; + +/** + * This model represents a property bag containing all options for creating or updating a {@link + * SearchIndexerDataSourceConnection data source connection}. + */ +public final class CreateOrUpdateDataSourceConnectionOptions { + private final SearchIndexerDataSourceConnection dataSourceConnection; + + private boolean onlyIfUnchanged; + private Boolean cacheResetRequirementsIgnored; + + /** + * Creates the property bag used to create or update a {@link SearchIndexerDataSourceConnection data source + * connection}. + * + * @param dataSourceConnection The {@link SearchIndexerDataSourceConnection data source connection} being created or + * updated. + * @throws NullPointerException If {@code dataSourceConnection} is null. + */ + public CreateOrUpdateDataSourceConnectionOptions(SearchIndexerDataSourceConnection dataSourceConnection) { + this.dataSourceConnection = Objects.requireNonNull(dataSourceConnection, + "'dataSourceConnection' cannot be null."); + } + + /** + * Gets the {@link SearchIndexerDataSourceConnection data source connection} that will be created or updated. + * + * @return The {@link SearchIndexerDataSourceConnection data source connection} that will be created or updated. + */ + public SearchIndexerDataSourceConnection getDataSourceConnection() { + return dataSourceConnection; + } + + /** + * Sets the flag that determines whether an update will only occur if the {@link SearchIndexerDataSourceConnection + * data source connection} has not been changed since the update has been triggered. + * + * @param onlyIfUnchanged Flag that determines whether an update will only occur if the {@link + * SearchIndexerDataSourceConnection data source connection} has not been changed since the update has been + * triggered. + * @return The updated CreateOrUpdateDataSourceConnectionOptions object. + */ + public CreateOrUpdateDataSourceConnectionOptions setOnlyIfUnchanged(boolean onlyIfUnchanged) { + this.onlyIfUnchanged = onlyIfUnchanged; + return this; + } + + /** + * Gets the flag that determines whether an update will only occur if the {@link SearchIndexerDataSourceConnection + * data source connection} has not been changed since the update has been triggered. + * + * @return Whether an update will only occur if the {@link SearchIndexerDataSourceConnection data source connection} + * has not been changed since the update has been triggered. + */ + public boolean isOnlyIfUnchanged() { + return onlyIfUnchanged; + } + + /** + * Sets an optional flag that determines whether the created or updated {@link SearchIndexerDataSourceConnection + * data source connection} ignores cache reset requirements. + * + * @param cacheResetRequirementsIgnored An optional flag that determines whether the created or updated {@link + * SearchIndexerDataSourceConnection data source connection} ignores cache reset requirements. + * @return The updated CreateOrUpdateDataSourceConnectionOptions object. + */ + public CreateOrUpdateDataSourceConnectionOptions setCacheResetRequirementsIgnored(Boolean cacheResetRequirementsIgnored) { + this.cacheResetRequirementsIgnored = cacheResetRequirementsIgnored; + return this; + } + + /** + * Gets an optional flag that determines whether the created or updated {@link SearchIndexerDataSourceConnection + * data source connection} ignores cache reset requirements. + * + * @return Whether the created or updated {@link SearchIndexerDataSourceConnection data source connection} ignores + * cache reset requirements. + */ + public Boolean isCacheResetRequirementsIgnored() { + return cacheResetRequirementsIgnored; + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java new file mode 100644 index 000000000000..a37711d82146 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.search.documents.indexes.models; + +import java.util.Objects; + +/** + * This model represents a property bag containing all options for creating or updating an {@link SearchIndexer + * indexer}. + */ +public class CreateOrUpdateIndexerOptions { + private final SearchIndexer indexer; + + private boolean onlyIfUnchanged; + private Boolean cacheReprocessingChangeDetectionDisabled; + private Boolean cacheResetRequirementsIgnored; + + /** + * Creates the property bag used to create or update an {@link SearchIndexer indexer}. + * + * @param indexer The {@link SearchIndexer indexer} being created or updated. + * @throws NullPointerException If {@code indexer} is null. + */ + public CreateOrUpdateIndexerOptions(SearchIndexer indexer) { + this.indexer = Objects.requireNonNull(indexer, "'indexer' cannot be null."); + } + + /** + * Gets the {@link SearchIndexer indexer} that will be created or updated. + * + * @return The {@link SearchIndexer indexer} that will be created or updated. + */ + public SearchIndexer getIndexer() { + return indexer; + } + + /** + * Sets the flag that determines whether an update will only occur if the {@link SearchIndexer indexer} has not been + * changed since the update has been triggered. + * + * @param onlyIfUnchanged Flag that determines whether an update will only occur if the {@link SearchIndexer + * indexer} has not been changed since the update has been triggered. + * @return The updated CreateOrUpdateIndexerOptions object. + */ + public CreateOrUpdateIndexerOptions setOnlyIfUnchanged(boolean onlyIfUnchanged) { + this.onlyIfUnchanged = onlyIfUnchanged; + return this; + } + + /** + * Gets the flag that determines whether an update will only occur if the {@link SearchIndexer indexer} has not been + * changed since the update has been triggered. + * + * @return Whether an update will only occur if the {@link SearchIndexer indexer} has not been changed since the + * update has been triggered. + */ + public boolean isOnlyIfUnchanged() { + return onlyIfUnchanged; + } + + /** + * Sets an optional flag that determines whether the created or updated {@link SearchIndexer indexer} disables cache + * reprocessing change detection. + * + * @param cacheReprocessingChangeDetectionDisabled An optional flag that determines whether the created or updated + * {@link SearchIndexer indexer} disables cache reprocessing change detection. + * @return The updated CreateOrUpdateIndexerOptions object. + */ + public CreateOrUpdateIndexerOptions setCacheReprocessingChangeDetectionDisabled( + Boolean cacheReprocessingChangeDetectionDisabled) { + this.cacheReprocessingChangeDetectionDisabled = cacheReprocessingChangeDetectionDisabled; + return this; + } + + /** + * Gets an optional flag that determines whether the created or updated {@link SearchIndexer indexer} disables cache + * reprocessing change detection. + * + * @return Whether the created or updated {@link SearchIndexer indexer} disables cache reprocessing change + * detection. + */ + public Boolean isCacheReprocessingChangeDetectionDisabled() { + return cacheReprocessingChangeDetectionDisabled; + } + + /** + * Sets an optional flag that determines whether the created or updated {@link SearchIndexer indexer} ignores cache + * reset requirements. + * + * @param cacheResetRequirementsIgnored An optional flag that determines whether the created or updated {@link + * SearchIndexer indexer} ignores cache reset requirements. + * @return The updated CreateOrUpdateIndexerOptions object. + */ + public CreateOrUpdateIndexerOptions setCacheResetRequirementsIgnored(Boolean cacheResetRequirementsIgnored) { + this.cacheResetRequirementsIgnored = cacheResetRequirementsIgnored; + return this; + } + + /** + * Gets an optional flag that determines whether the created or updated {@link SearchIndexer indexer} ignores cache + * reset requirements. + * + * @return Whether the created or updated {@link SearchIndexer indexer} ignores cache reset requirements. + */ + public Boolean isCacheResetRequirementsIgnored() { + return cacheResetRequirementsIgnored; + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java new file mode 100644 index 000000000000..a6fc76ef5ee9 --- /dev/null +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.search.documents.indexes.models; + +import java.util.Objects; + +/** + * This model represents a property bag containing all options for creating or updating a {@link SearchIndexerSkillset + * skillset}. + */ +public final class CreateOrUpdateSkillsetOptions { + private final SearchIndexerSkillset skillset; + + private boolean onlyIfUnchanged; + private Boolean cacheReprocessingChangeDetectionDisabled; + private Boolean cacheResetRequirementsIgnored; + + /** + * Creates the property bag used to create or update a {@link SearchIndexerSkillset skillset}. + * + * @param skillset The {@link SearchIndexerSkillset skillset} being created or updated. + * @throws NullPointerException If {@code skillset} is null. + */ + public CreateOrUpdateSkillsetOptions(SearchIndexerSkillset skillset) { + this.skillset = Objects.requireNonNull(skillset, "'skillset' cannot be null."); + } + + /** + * Gets the {@link SearchIndexerSkillset skillset} that will be created or updated. + * + * @return The {@link SearchIndexerSkillset skillset} that will be created or updated. + */ + public SearchIndexerSkillset getSkillset() { + return skillset; + } + + /** + * Sets the flag that determines whether an update will only occur if the {@link SearchIndexerSkillset skillset} has + * not been changed since the update has been triggered. + * + * @param onlyIfUnchanged Flag that determines whether an update will only occur if the {@link SearchIndexerSkillset + * skillset} has not been changed since the update has been triggered. + * @return The updated CreateOrUpdateSkillsetOptions object. + */ + public CreateOrUpdateSkillsetOptions setOnlyIfUnchanged(boolean onlyIfUnchanged) { + this.onlyIfUnchanged = onlyIfUnchanged; + return this; + } + + /** + * Gets the flag that determines whether an update will only occur if the {@link SearchIndexerSkillset skillset} has + * not been changed since the update has been triggered. + * + * @return Whether an update will only occur if the {@link SearchIndexerSkillset skillset} has not been changed + * since the update has been triggered. + */ + public boolean isOnlyIfUnchanged() { + return onlyIfUnchanged; + } + + /** + * Sets an optional flag that determines whether the created or updated {@link SearchIndexerSkillset skillset} + * disables cache reprocessing change detection. + * + * @param cacheReprocessingChangeDetectionDisabled An optional flag that determines whether the created or updated + * {@link SearchIndexerSkillset skillset} disables cache reprocessing change detection. + * @return The updated CreateOrUpdateSkillsetOptions object. + */ + public CreateOrUpdateSkillsetOptions setCacheReprocessingChangeDetectionDisabled( + Boolean cacheReprocessingChangeDetectionDisabled) { + this.cacheReprocessingChangeDetectionDisabled = cacheReprocessingChangeDetectionDisabled; + return this; + } + + /** + * Gets an optional flag that determines whether the created or updated {@link SearchIndexerSkillset skillset} + * disables cache reprocessing change detection. + * + * @return Whether the created or updated {@link SearchIndexerSkillset skillset} disables cache reprocessing change + * detection. + */ + public Boolean isCacheReprocessingChangeDetectionDisabled() { + return cacheReprocessingChangeDetectionDisabled; + } + + /** + * Sets an optional flag that determines whether the created or updated {@link SearchIndexerSkillset skillset} + * ignores cache reset requirements. + * + * @param cacheResetRequirementsIgnored An optional flag that determines whether the created or updated {@link + * SearchIndexerSkillset skillset} ignores cache reset requirements. + * @return The updated CreateOrUpdateSkillsetOptions object. + */ + public CreateOrUpdateSkillsetOptions setCacheResetRequirementsIgnored(Boolean cacheResetRequirementsIgnored) { + this.cacheResetRequirementsIgnored = cacheResetRequirementsIgnored; + return this; + } + + /** + * Gets an optional flag that determines whether the created or updated {@link SearchIndexerSkillset skillset} + * ignores cache reset requirements. + * + * @return Whether the created or updated {@link SearchIndexerSkillset skillset} ignores cache reset requirements. + */ + public Boolean isCacheResetRequirementsIgnored() { + return cacheResetRequirementsIgnored; + } +} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java index b2dfbfa20f9b..e4203b6e90de 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSource.java @@ -206,8 +206,6 @@ public static KnowledgeSource fromJson(JsonReader jsonReader) throws IOException // Use the discriminator value to determine which subtype should be deserialized. if ("searchIndex".equals(discriminatorValue)) { return SearchIndexKnowledgeSource.fromJson(readerToUse.reset()); - } else if ("web".equals(discriminatorValue)) { - return WebKnowledgeSource.fromJson(readerToUse.reset()); } else if ("azureBlob".equals(discriminatorValue)) { return AzureBlobKnowledgeSource.fromJson(readerToUse.reset()); } else { diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java index 2b749993a7fa..b88629a02df5 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/KnowledgeSourceKind.java @@ -26,12 +26,6 @@ public final class KnowledgeSourceKind extends ExpandableStringEnum { - boolean nameFound = false; - String name = null; - String description = null; - String eTag = null; - SearchResourceEncryptionKey encryptionKey = null; - boolean webParametersFound = false; - WebKnowledgeSourceParameters webParameters = null; - KnowledgeSourceKind kind = KnowledgeSourceKind.WEB; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("name".equals(fieldName)) { - name = reader.getString(); - nameFound = true; - } else if ("description".equals(fieldName)) { - description = reader.getString(); - } else if ("@odata.etag".equals(fieldName)) { - eTag = reader.getString(); - } else if ("encryptionKey".equals(fieldName)) { - encryptionKey = SearchResourceEncryptionKey.fromJson(reader); - } else if ("webParameters".equals(fieldName)) { - webParameters = WebKnowledgeSourceParameters.fromJson(reader); - webParametersFound = true; - } else if ("kind".equals(fieldName)) { - kind = KnowledgeSourceKind.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - if (nameFound && webParametersFound) { - WebKnowledgeSource deserializedWebKnowledgeSource = new WebKnowledgeSource(name, webParameters); - deserializedWebKnowledgeSource.setDescription(description); - deserializedWebKnowledgeSource.setETag(eTag); - deserializedWebKnowledgeSource.setEncryptionKey(encryptionKey); - deserializedWebKnowledgeSource.kind = kind; - - return deserializedWebKnowledgeSource; - } - List missingProperties = new ArrayList<>(); - if (!nameFound) { - missingProperties.add("name"); - } - if (!webParametersFound) { - missingProperties.add("webParameters"); - } - - throw new IllegalStateException( - "Missing required property/properties: " + String.join(", ", missingProperties)); - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java deleted file mode 100644 index e16d84810311..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceAllowedDomain.java +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.indexes.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Configuration for web knowledge source domain. - */ -@Fluent -public final class WebKnowledgeSourceAllowedDomain implements JsonSerializable { - /* - * The address of the domain. - */ - @Generated - private final String address; - - /* - * whether or not to include subpages from this domain. - */ - @Generated - private Boolean includeSubpages; - - /* - * The ranking adjustment to perform on the web results. - */ - @Generated - private WebKnowledgeSourceRankingAdjustment rankingAdjustment; - - /** - * Creates an instance of WebKnowledgeSourceAllowedDomain class. - * - * @param address the address value to set. - */ - @Generated - public WebKnowledgeSourceAllowedDomain(String address) { - this.address = address; - } - - /** - * Get the address property: The address of the domain. - * - * @return the address value. - */ - @Generated - public String getAddress() { - return this.address; - } - - /** - * Get the includeSubpages property: whether or not to include subpages from this domain. - * - * @return the includeSubpages value. - */ - @Generated - public Boolean isIncludeSubpages() { - return this.includeSubpages; - } - - /** - * Set the includeSubpages property: whether or not to include subpages from this domain. - * - * @param includeSubpages the includeSubpages value to set. - * @return the WebKnowledgeSourceAllowedDomain object itself. - */ - @Generated - public WebKnowledgeSourceAllowedDomain setIncludeSubpages(Boolean includeSubpages) { - this.includeSubpages = includeSubpages; - return this; - } - - /** - * Get the rankingAdjustment property: The ranking adjustment to perform on the web results. - * - * @return the rankingAdjustment value. - */ - @Generated - public WebKnowledgeSourceRankingAdjustment getRankingAdjustment() { - return this.rankingAdjustment; - } - - /** - * Set the rankingAdjustment property: The ranking adjustment to perform on the web results. - * - * @param rankingAdjustment the rankingAdjustment value to set. - * @return the WebKnowledgeSourceAllowedDomain object itself. - */ - @Generated - public WebKnowledgeSourceAllowedDomain setRankingAdjustment(WebKnowledgeSourceRankingAdjustment rankingAdjustment) { - this.rankingAdjustment = rankingAdjustment; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("address", this.address); - jsonWriter.writeBooleanField("includeSubpages", this.includeSubpages); - jsonWriter.writeStringField("rankingAdjustment", - this.rankingAdjustment == null ? null : this.rankingAdjustment.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of WebKnowledgeSourceAllowedDomain from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of WebKnowledgeSourceAllowedDomain if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the WebKnowledgeSourceAllowedDomain. - */ - @Generated - public static WebKnowledgeSourceAllowedDomain fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - boolean addressFound = false; - String address = null; - Boolean includeSubpages = null; - WebKnowledgeSourceRankingAdjustment rankingAdjustment = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("address".equals(fieldName)) { - address = reader.getString(); - addressFound = true; - } else if ("includeSubpages".equals(fieldName)) { - includeSubpages = reader.getNullable(JsonReader::getBoolean); - } else if ("rankingAdjustment".equals(fieldName)) { - rankingAdjustment = WebKnowledgeSourceRankingAdjustment.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - if (addressFound) { - WebKnowledgeSourceAllowedDomain deserializedWebKnowledgeSourceAllowedDomain - = new WebKnowledgeSourceAllowedDomain(address); - deserializedWebKnowledgeSourceAllowedDomain.includeSubpages = includeSubpages; - deserializedWebKnowledgeSourceAllowedDomain.rankingAdjustment = rankingAdjustment; - - return deserializedWebKnowledgeSourceAllowedDomain; - } - throw new IllegalStateException("Missing required property: address"); - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java deleted file mode 100644 index 16676d790a15..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceBlockedDomain.java +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.indexes.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Configuration for web knowledge source domain. - */ -@Fluent -public final class WebKnowledgeSourceBlockedDomain implements JsonSerializable { - /* - * The address of the domain. - */ - @Generated - private final String address; - - /* - * whether or not to include subpages from this domain. - */ - @Generated - private Boolean includeSubpages; - - /** - * Creates an instance of WebKnowledgeSourceBlockedDomain class. - * - * @param address the address value to set. - */ - @Generated - public WebKnowledgeSourceBlockedDomain(String address) { - this.address = address; - } - - /** - * Get the address property: The address of the domain. - * - * @return the address value. - */ - @Generated - public String getAddress() { - return this.address; - } - - /** - * Get the includeSubpages property: whether or not to include subpages from this domain. - * - * @return the includeSubpages value. - */ - @Generated - public Boolean isIncludeSubpages() { - return this.includeSubpages; - } - - /** - * Set the includeSubpages property: whether or not to include subpages from this domain. - * - * @param includeSubpages the includeSubpages value to set. - * @return the WebKnowledgeSourceBlockedDomain object itself. - */ - @Generated - public WebKnowledgeSourceBlockedDomain setIncludeSubpages(Boolean includeSubpages) { - this.includeSubpages = includeSubpages; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("address", this.address); - jsonWriter.writeBooleanField("includeSubpages", this.includeSubpages); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of WebKnowledgeSourceBlockedDomain from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of WebKnowledgeSourceBlockedDomain if the JsonReader was pointing to an instance of it, or - * null if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the WebKnowledgeSourceBlockedDomain. - */ - @Generated - public static WebKnowledgeSourceBlockedDomain fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - boolean addressFound = false; - String address = null; - Boolean includeSubpages = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("address".equals(fieldName)) { - address = reader.getString(); - addressFound = true; - } else if ("includeSubpages".equals(fieldName)) { - includeSubpages = reader.getNullable(JsonReader::getBoolean); - } else { - reader.skipChildren(); - } - } - if (addressFound) { - WebKnowledgeSourceBlockedDomain deserializedWebKnowledgeSourceBlockedDomain - = new WebKnowledgeSourceBlockedDomain(address); - deserializedWebKnowledgeSourceBlockedDomain.includeSubpages = includeSubpages; - - return deserializedWebKnowledgeSourceBlockedDomain; - } - throw new IllegalStateException("Missing required property: address"); - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java deleted file mode 100644 index 74718d166657..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceParameters.java +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.indexes.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; -import java.util.List; - -/** - * Parameters for web knowledge source. - */ -@Fluent -public final class WebKnowledgeSourceParameters implements JsonSerializable { - /* - * An explicit identity to use for this knowledge source. - */ - @Generated - private SearchIndexerDataIdentity identity; - - /* - * The ResourceId of the Bing Search resource to use for web results. - */ - @Generated - private String bingResourceId; - - /* - * The language of the web results. - */ - @Generated - private String language; - - /* - * The market of the web results. - */ - @Generated - private String market; - - /* - * The freshness of web results. - */ - @Generated - private String freshness; - - /* - * Domains that are allowed for web results - */ - @Generated - private List allowedDomains; - - /* - * Domains that are blocked from web results - */ - @Generated - private List blockedDomains; - - /** - * Creates an instance of WebKnowledgeSourceParameters class. - */ - @Generated - public WebKnowledgeSourceParameters() { - } - - /** - * Get the identity property: An explicit identity to use for this knowledge source. - * - * @return the identity value. - */ - @Generated - public SearchIndexerDataIdentity getIdentity() { - return this.identity; - } - - /** - * Set the identity property: An explicit identity to use for this knowledge source. - * - * @param identity the identity value to set. - * @return the WebKnowledgeSourceParameters object itself. - */ - @Generated - public WebKnowledgeSourceParameters setIdentity(SearchIndexerDataIdentity identity) { - this.identity = identity; - return this; - } - - /** - * Get the bingResourceId property: The ResourceId of the Bing Search resource to use for web results. - * - * @return the bingResourceId value. - */ - @Generated - public String getBingResourceId() { - return this.bingResourceId; - } - - /** - * Set the bingResourceId property: The ResourceId of the Bing Search resource to use for web results. - * - * @param bingResourceId the bingResourceId value to set. - * @return the WebKnowledgeSourceParameters object itself. - */ - @Generated - public WebKnowledgeSourceParameters setBingResourceId(String bingResourceId) { - this.bingResourceId = bingResourceId; - return this; - } - - /** - * Get the language property: The language of the web results. - * - * @return the language value. - */ - @Generated - public String getLanguage() { - return this.language; - } - - /** - * Set the language property: The language of the web results. - * - * @param language the language value to set. - * @return the WebKnowledgeSourceParameters object itself. - */ - @Generated - public WebKnowledgeSourceParameters setLanguage(String language) { - this.language = language; - return this; - } - - /** - * Get the market property: The market of the web results. - * - * @return the market value. - */ - @Generated - public String getMarket() { - return this.market; - } - - /** - * Set the market property: The market of the web results. - * - * @param market the market value to set. - * @return the WebKnowledgeSourceParameters object itself. - */ - @Generated - public WebKnowledgeSourceParameters setMarket(String market) { - this.market = market; - return this; - } - - /** - * Get the freshness property: The freshness of web results. - * - * @return the freshness value. - */ - @Generated - public String getFreshness() { - return this.freshness; - } - - /** - * Set the freshness property: The freshness of web results. - * - * @param freshness the freshness value to set. - * @return the WebKnowledgeSourceParameters object itself. - */ - @Generated - public WebKnowledgeSourceParameters setFreshness(String freshness) { - this.freshness = freshness; - return this; - } - - /** - * Get the allowedDomains property: Domains that are allowed for web results. - * - * @return the allowedDomains value. - */ - @Generated - public List getAllowedDomains() { - return this.allowedDomains; - } - - /** - * Set the allowedDomains property: Domains that are allowed for web results. - * - * @param allowedDomains the allowedDomains value to set. - * @return the WebKnowledgeSourceParameters object itself. - */ - @Generated - public WebKnowledgeSourceParameters setAllowedDomains(List allowedDomains) { - this.allowedDomains = allowedDomains; - return this; - } - - /** - * Get the blockedDomains property: Domains that are blocked from web results. - * - * @return the blockedDomains value. - */ - @Generated - public List getBlockedDomains() { - return this.blockedDomains; - } - - /** - * Set the blockedDomains property: Domains that are blocked from web results. - * - * @param blockedDomains the blockedDomains value to set. - * @return the WebKnowledgeSourceParameters object itself. - */ - @Generated - public WebKnowledgeSourceParameters setBlockedDomains(List blockedDomains) { - this.blockedDomains = blockedDomains; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeJsonField("identity", this.identity); - jsonWriter.writeStringField("bingResourceId", this.bingResourceId); - jsonWriter.writeStringField("language", this.language); - jsonWriter.writeStringField("market", this.market); - jsonWriter.writeStringField("freshness", this.freshness); - jsonWriter.writeArrayField("allowedDomains", this.allowedDomains, - (writer, element) -> writer.writeJson(element)); - jsonWriter.writeArrayField("blockedDomains", this.blockedDomains, - (writer, element) -> writer.writeJson(element)); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of WebKnowledgeSourceParameters from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of WebKnowledgeSourceParameters if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the WebKnowledgeSourceParameters. - */ - @Generated - public static WebKnowledgeSourceParameters fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - WebKnowledgeSourceParameters deserializedWebKnowledgeSourceParameters = new WebKnowledgeSourceParameters(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("identity".equals(fieldName)) { - deserializedWebKnowledgeSourceParameters.identity = SearchIndexerDataIdentity.fromJson(reader); - } else if ("bingResourceId".equals(fieldName)) { - deserializedWebKnowledgeSourceParameters.bingResourceId = reader.getString(); - } else if ("language".equals(fieldName)) { - deserializedWebKnowledgeSourceParameters.language = reader.getString(); - } else if ("market".equals(fieldName)) { - deserializedWebKnowledgeSourceParameters.market = reader.getString(); - } else if ("freshness".equals(fieldName)) { - deserializedWebKnowledgeSourceParameters.freshness = reader.getString(); - } else if ("allowedDomains".equals(fieldName)) { - List allowedDomains - = reader.readArray(reader1 -> WebKnowledgeSourceAllowedDomain.fromJson(reader1)); - deserializedWebKnowledgeSourceParameters.allowedDomains = allowedDomains; - } else if ("blockedDomains".equals(fieldName)) { - List blockedDomains - = reader.readArray(reader1 -> WebKnowledgeSourceBlockedDomain.fromJson(reader1)); - deserializedWebKnowledgeSourceParameters.blockedDomains = blockedDomains; - } else { - reader.skipChildren(); - } - } - - return deserializedWebKnowledgeSourceParameters; - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java deleted file mode 100644 index 858c196a9fe0..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/WebKnowledgeSourceRankingAdjustment.java +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.indexes.models; - -import com.azure.core.annotation.Generated; -import com.azure.core.util.ExpandableStringEnum; -import java.util.Collection; - -/** - * The ranking adjustment to perform on the web results. - */ -public final class WebKnowledgeSourceRankingAdjustment - extends ExpandableStringEnum { - /** - * Raises the ranking of the chosen domain or subpage so it appears higher in the search results. - */ - @Generated - public static final WebKnowledgeSourceRankingAdjustment BOOST = fromString("boost"); - - /** - * Applies a stronger positive weight than Boost, pushing the selected domain or subpage towards the very top of the - * results. - */ - @Generated - public static final WebKnowledgeSourceRankingAdjustment SUPER_BOOST = fromString("superBoost"); - - /** - * Lowers the ranking of the specified domain or subpage so it shows up further down the results list. - */ - @Generated - public static final WebKnowledgeSourceRankingAdjustment DEMOTE = fromString("demote"); - - /** - * Creates a new instance of WebKnowledgeSourceRankingAdjustment value. - * - * @deprecated Use the {@link #fromString(String)} factory method. - */ - @Generated - @Deprecated - public WebKnowledgeSourceRankingAdjustment() { - } - - /** - * Creates or finds a WebKnowledgeSourceRankingAdjustment from its string representation. - * - * @param name a name to look for. - * @return the corresponding WebKnowledgeSourceRankingAdjustment. - */ - @Generated - public static WebKnowledgeSourceRankingAdjustment fromString(String name) { - return fromString(name, WebKnowledgeSourceRankingAdjustment.class); - } - - /** - * Gets known WebKnowledgeSourceRankingAdjustment values. - * - * @return known WebKnowledgeSourceRankingAdjustment values. - */ - @Generated - public static Collection values() { - return values(WebKnowledgeSourceRankingAdjustment.class); - } -} diff --git a/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/SearchJavaDocCodeSnippets.java b/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/SearchJavaDocCodeSnippets.java index c059e375dd61..cde99934e311 100644 --- a/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/SearchJavaDocCodeSnippets.java +++ b/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/SearchJavaDocCodeSnippets.java @@ -15,12 +15,16 @@ import com.azure.search.documents.indexes.SearchIndexerClientBuilder; import com.azure.search.documents.indexes.models.AnalyzeTextOptions; import com.azure.search.documents.indexes.models.AnalyzedTokenInfo; +import com.azure.search.documents.indexes.models.CreateOrUpdateDataSourceConnectionOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateIndexerOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateSkillsetOptions; import com.azure.search.documents.indexes.models.FieldMapping; import com.azure.search.documents.indexes.models.IndexDocumentsBatch; import com.azure.search.documents.indexes.models.InputFieldMappingEntry; import com.azure.search.documents.indexes.models.LexicalTokenizerName; import com.azure.search.documents.indexes.models.OcrSkill; import com.azure.search.documents.indexes.models.OutputFieldMappingEntry; +import com.azure.search.documents.indexes.models.SearchAlias; import com.azure.search.documents.indexes.models.SearchField; import com.azure.search.documents.indexes.models.SearchFieldDataType; import com.azure.search.documents.indexes.models.SearchIndex; @@ -680,12 +684,8 @@ public void searchDocumentsAsync() { AtomicLong numberOfDocumentsReturned = new AtomicLong(); searchPagedFlux.byPage() .takeUntil(page -> { - if (numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT) { - // Reached the $skip limit, stop requesting more documents. - return true; - } - - return false; + // Reached the $skip limit, stop requesting more documents. + return numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT; }) .subscribe(resultResponse -> { for (SearchResult result: resultResponse.getValue()) { @@ -699,7 +699,7 @@ public void searchDocumentsAsync() { } /** - * Code snippet for {@link SearchAsyncClient#search(String, SearchOptions, Context)} + * Code snippet for {@link SearchAsyncClient#search(String, SearchOptions)} */ public void searchDocumentsWithOptionsAsync() { // BEGIN: com.azure.search.documents.SearchAsyncClient.search#String-SearchOptions @@ -711,12 +711,8 @@ public void searchDocumentsWithOptionsAsync() { AtomicLong numberOfDocumentsReturned = new AtomicLong(); pagedFlux.byPage() .takeUntil(page -> { - if (numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT) { - // Reached the $skip limit, stop requesting more documents. - return true; - } - - return false; + // Reached the $skip limit, stop requesting more documents. + return numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT; }) .subscribe(searchResultResponse -> searchResultResponse.getValue().forEach(searchDocument -> { for (Map.Entry keyValuePair @@ -1700,6 +1696,26 @@ public void createOrUpdateIndexerWithResponse() { // END: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateIndexerWithResponse#SearchIndexer-boolean-Context } + /** + * Code snippet for {@link SearchIndexerClient#createOrUpdateIndexerWithResponse(CreateOrUpdateIndexerOptions, Context)} + */ + public void createOrUpdateIndexerWithResponse2() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateIndexerWithResponse#CreateOrUpdateIndexerOptions-Context + SearchIndexer searchIndexerFromService = SEARCH_INDEXER_CLIENT.getIndexer("searchIndexer"); + searchIndexerFromService.setFieldMappings(Collections.singletonList( + new FieldMapping("hotelName").setTargetFieldName("HotelName"))); + CreateOrUpdateIndexerOptions options = new CreateOrUpdateIndexerOptions(searchIndexerFromService) + .setOnlyIfUnchanged(true) + .setCacheReprocessingChangeDetectionDisabled(false) + .setCacheResetRequirementsIgnored(true); + Response indexerFromService = SEARCH_INDEXER_CLIENT.createOrUpdateIndexerWithResponse( + options, new Context(KEY_1, VALUE_1)); + System.out.printf("The status code of the response is %s.%nThe indexer name is %s. " + + "The target field name of indexer is %s.%n", indexerFromService.getStatusCode(), + indexerFromService.getValue().getName(), + indexerFromService.getValue().getFieldMappings().get(0).getTargetFieldName()); + // END: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateIndexerWithResponse#CreateOrUpdateIndexerOptions-Context + } /** * Code snippet for {@link SearchIndexerClient#deleteIndexer(String)} @@ -1784,6 +1800,40 @@ public void getIndexerStatusWithResponse() { // END: com.azure.search.documents.indexes.SearchIndexerClient.getIndexerStatusWithResponse#String-Context } + /** + * Code snippet for {@link SearchIndexerClient#resetDocuments(String, Boolean, List, List)} + */ + public void resetDocuments() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerClient.resetDocuments#String-Boolean-List-List + // Reset the documents with keys 1234 and 4321. + SEARCH_INDEXER_CLIENT.resetDocuments("searchIndexer", false, Arrays.asList("1234", "4321"), null); + + // Clear the previous documents to be reset and replace them with documents 1235 and 5231. + SEARCH_INDEXER_CLIENT.resetDocuments("searchIndexer", true, Arrays.asList("1235", "5321"), null); + // END: com.azure.search.documents.indexes.SearchIndexerClient.resetDocuments#String-Boolean-List-List + } + + /** + * Code snippet for {@link SearchIndexerClient#resetDocumentsWithResponse(SearchIndexer, Boolean, List, List, Context)} + */ + public void resetDocumentsWithResponse() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerClient.resetDocumentsWithResponse#SearchIndexer-Boolean-List-List-Context + SearchIndexer searchIndexer = SEARCH_INDEXER_CLIENT.getIndexer("searchIndexer"); + + // Reset the documents with keys 1234 and 4321. + Response resetDocsResult = SEARCH_INDEXER_CLIENT.resetDocumentsWithResponse(searchIndexer, false, + Arrays.asList("1234", "4321"), null, new Context(KEY_1, VALUE_1)); + System.out.printf("Requesting documents to be reset completed with status code %d.%n", + resetDocsResult.getStatusCode()); + + // Clear the previous documents to be reset and replace them with documents 1235 and 5231. + resetDocsResult = SEARCH_INDEXER_CLIENT.resetDocumentsWithResponse(searchIndexer, true, + Arrays.asList("1235", "5321"), null, new Context(KEY_1, VALUE_1)); + System.out.printf("Overwriting the documents to be reset completed with status code %d.%n", + resetDocsResult.getStatusCode()); + // END: com.azure.search.documents.indexes.SearchIndexerClient.resetDocumentsWithResponse#SearchIndexer-Boolean-List-List-Context + } + /** * Code snippet for creating {@link SearchIndexerClient#createDataSourceConnection(SearchIndexerDataSourceConnection)}. */ @@ -1929,6 +1979,25 @@ public void createOrUpdateDataSourceWithResponse() { // END: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateDataSourceConnectionWithResponse#SearchIndexerDataSourceConnection-boolean-Context } + /** + * Code snippet for {@link SearchIndexerClient#createOrUpdateDataSourceConnectionWithResponse(CreateOrUpdateDataSourceConnectionOptions, Context)} + */ + public void createOrUpdateDataSourceWithResponse2() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateDataSourceConnectionWithResponse#CreateOrUpdateDataSourceConnectionOptions-Context + SearchIndexerDataSourceConnection dataSource = SEARCH_INDEXER_CLIENT.getDataSourceConnection("dataSource"); + dataSource.setContainer(new SearchIndexerDataContainer("updatecontainer")); + CreateOrUpdateDataSourceConnectionOptions options = new CreateOrUpdateDataSourceConnectionOptions(dataSource) + .setOnlyIfUnchanged(true) + .setCacheResetRequirementsIgnored(true); + + Response updateDataSource = SEARCH_INDEXER_CLIENT + .createOrUpdateDataSourceConnectionWithResponse(options, new Context(KEY_1, VALUE_1)); + System.out.printf("The status code of the response is %s.%nThe dataSource name is %s. " + + "The container name of dataSource is %s.%n", updateDataSource.getStatusCode(), + updateDataSource.getValue().getName(), updateDataSource.getValue().getContainer().getName()); + // END: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateDataSourceConnectionWithResponse#CreateOrUpdateDataSourceConnectionOptions-Context + } + /** * Code snippet for {@link SearchIndexerClient#deleteDataSourceConnection(String)} */ @@ -2121,6 +2190,26 @@ public void createOrUpdateIndexerSkillsetWithResponse() { // END: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateSkillsetWithResponse#SearchIndexerSkillset-boolean-Context } + /** + * Code snippet for {@link SearchIndexerClient#createOrUpdateSkillsetWithResponse(CreateOrUpdateSkillsetOptions, Context)} + */ + public void createOrUpdateIndexerSkillsetWithResponse2() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateSkillsetWithResponse#CreateOrUpdateSkillsetOptions-Context + SearchIndexerSkillset indexerSkillset = SEARCH_INDEXER_CLIENT.getSkillset("searchIndexerSkillset"); + indexerSkillset.setDescription("This is new description!"); + CreateOrUpdateSkillsetOptions options = new CreateOrUpdateSkillsetOptions(indexerSkillset) + .setOnlyIfUnchanged(true) + .setCacheReprocessingChangeDetectionDisabled(false) + .setCacheResetRequirementsIgnored(true); + Response updateSkillsetResponse = SEARCH_INDEXER_CLIENT.createOrUpdateSkillsetWithResponse( + options, new Context(KEY_1, VALUE_1)); + System.out.printf("The status code of the response is %s.%nThe indexer skillset name is %s. " + + "The description of indexer skillset is %s.%n", updateSkillsetResponse.getStatusCode(), + updateSkillsetResponse.getValue().getName(), + updateSkillsetResponse.getValue().getDescription()); + // END: com.azure.search.documents.indexes.SearchIndexerClient.createOrUpdateSkillsetWithResponse#CreateOrUpdateSkillsetOptions-Context + } + /** * Code snippet for {@link SearchIndexerClient#deleteSkillset(String)} */ @@ -2268,6 +2357,29 @@ public void createOrUpdateIndexerWithResponseAsync() { // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateIndexerWithResponse#SearchIndexer-boolean } + /** + * Code snippet for {@link SearchIndexerAsyncClient#createOrUpdateIndexerWithResponse(CreateOrUpdateIndexerOptions)} + */ + public void createOrUpdateIndexerWithResponseAsync2() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateIndexerWithResponse#CreateOrUpdateIndexerOptions + SEARCH_INDEXER_ASYNC_CLIENT.getIndexer("searchIndexer") + .flatMap(searchIndexerFromService -> { + searchIndexerFromService.setFieldMappings(Collections.singletonList( + new FieldMapping("hotelName").setTargetFieldName("HotelName"))); + return SEARCH_INDEXER_ASYNC_CLIENT.createOrUpdateIndexerWithResponse( + new CreateOrUpdateIndexerOptions(searchIndexerFromService) + .setOnlyIfUnchanged(true) + .setCacheReprocessingChangeDetectionDisabled(false) + .setCacheResetRequirementsIgnored(true)); + }) + .subscribe(indexerFromService -> + System.out.printf("The status code of the response is %s.%nThe indexer name is %s. " + + "The target field name of indexer is %s.%n", indexerFromService.getStatusCode(), + indexerFromService.getValue().getName(), + indexerFromService.getValue().getFieldMappings().get(0).getTargetFieldName())); + // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateIndexerWithResponse#CreateOrUpdateIndexerOptions + } + /** * Code snippet for {@link SearchIndexerAsyncClient#deleteIndexer(String)} */ @@ -2356,6 +2468,41 @@ public void getIndexerStatusWithResponseAsync() { // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.getIndexerStatusWithResponse#String } + /** + * Code snippet for {@link SearchIndexerAsyncClient#resetDocuments(String, Boolean, List, List)} + */ + public void resetDocumentsAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetDocuments#String-Boolean-List-List + // Reset the documents with keys 1234 and 4321. + SEARCH_INDEXER_ASYNC_CLIENT.resetDocuments("searchIndexer", false, Arrays.asList("1234", "4321"), null) + // Clear the previous documents to be reset and replace them with documents 1235 and 5231. + .then(SEARCH_INDEXER_ASYNC_CLIENT.resetDocuments("searchIndexer", true, Arrays.asList("1235", "5321"), null)) + .subscribe(); + // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetDocuments#String-Boolean-List-List + } + + /** + * Code snippet for {@link SearchIndexerAsyncClient#resetDocumentsWithResponse(SearchIndexer, Boolean, List, List)} + */ + public void resetDocumentsWithResponseAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetDocumentsWithResponse#SearchIndexer-Boolean-List-List + SEARCH_INDEXER_ASYNC_CLIENT.getIndexer("searchIndexer") + .flatMap(searchIndexer -> SEARCH_INDEXER_ASYNC_CLIENT.resetDocumentsWithResponse(searchIndexer, false, + Arrays.asList("1234", "4321"), null) + .flatMap(resetDocsResult -> { + System.out.printf("Requesting documents to be reset completed with status code %d.%n", + resetDocsResult.getStatusCode()); + + // Clear the previous documents to be reset and replace them with documents 1235 and 5231. + return SEARCH_INDEXER_ASYNC_CLIENT.resetDocumentsWithResponse(searchIndexer, true, + Arrays.asList("1235", "5321"), null); + })) + .subscribe(resetDocsResult -> + System.out.printf("Overwriting the documents to be reset completed with status code %d.%n", + resetDocsResult.getStatusCode())); + // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetDocumentsWithResponse#SearchIndexer-Boolean-List-List + } + /** * Code snippet for creating {@link SearchIndexerAsyncClient#createDataSourceConnection(SearchIndexerDataSourceConnection)}. */ @@ -2466,8 +2613,25 @@ public void createOrUpdateDataSourceWithResponseAsync() { // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateDataSourceConnectionWithResponse#SearchIndexerDataSourceConnection-boolean } - - + /** + * Code snippet for {@link SearchIndexerAsyncClient#createOrUpdateDataSourceConnectionWithResponse(CreateOrUpdateDataSourceConnectionOptions)} + */ + public void createOrUpdateDataSourceWithResponseAsync2() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateDataSourceConnectionWithResponse#CreateOrUpdateDataSourceConnectionOptions + SEARCH_INDEXER_ASYNC_CLIENT.getDataSourceConnection("dataSource") + .flatMap(dataSource -> { + dataSource.setContainer(new SearchIndexerDataContainer("updatecontainer")); + return SEARCH_INDEXER_ASYNC_CLIENT.createOrUpdateDataSourceConnectionWithResponse( + new CreateOrUpdateDataSourceConnectionOptions(dataSource) + .setOnlyIfUnchanged(true) + .setCacheResetRequirementsIgnored(true)); + }) + .subscribe(updateDataSource -> + System.out.printf("The status code of the response is %s.%nThe dataSource name is %s. " + + "The container name of dataSource is %s.%n", updateDataSource.getStatusCode(), + updateDataSource.getValue().getName(), updateDataSource.getValue().getContainer().getName())); + // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateDataSourceConnectionWithResponse#CreateOrUpdateDataSourceConnectionOptions + } /** * Code snippet for {@link SearchIndexerAsyncClient#deleteDataSourceConnection(String)} @@ -2630,6 +2794,27 @@ public void createOrUpdateIndexerSkillsetWithResponseAsync() { // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateSkillsetWithResponse#SearchIndexerSkillset-boolean } + /** + * Code snippet for {@link SearchIndexerAsyncClient#createOrUpdateSkillsetWithResponse(CreateOrUpdateSkillsetOptions)} + */ + public void createOrUpdateIndexerSkillsetWithResponseAsync2() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateSkillsetWithResponse#CreateOrUpdateSkillsetOptions + SEARCH_INDEXER_ASYNC_CLIENT.getSkillset("searchIndexerSkillset") + .flatMap(indexerSkillset -> { + indexerSkillset.setDescription("This is new description!"); + return SEARCH_INDEXER_ASYNC_CLIENT.createOrUpdateSkillsetWithResponse( + new CreateOrUpdateSkillsetOptions(indexerSkillset) + .setOnlyIfUnchanged(true) + .setCacheReprocessingChangeDetectionDisabled(false) + .setCacheResetRequirementsIgnored(true)); + }) + .subscribe(updateSkillsetResponse -> + System.out.printf("The status code of the response is %s.%nThe indexer skillset name is %s. " + + "The description of indexer skillset is %s.%n", updateSkillsetResponse.getStatusCode(), + updateSkillsetResponse.getValue().getName(), + updateSkillsetResponse.getValue().getDescription())); + // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.createOrUpdateSkillsetWithResponse#CreateOrUpdateSkillsetOptions + } /** * Code snippet for {@link SearchIndexerAsyncClient#deleteSkillset(String)} @@ -2653,4 +2838,307 @@ public void deleteSearchIndexerSkillsetWithResponseAsync() { System.out.printf("The status code of the response is %d.%n", deleteResponse.getStatusCode())); // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.deleteSkillsetWithResponse#SearchIndexerSkillset-boolean } + + /** + * Code snippet for {@link SearchIndexerClient#resetSkills(String, List)} + */ + public void resetSkills() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerClient.resetSkills#String-List + // Reset the "myOcr" and "myText" skills. + SEARCH_INDEXER_CLIENT.resetSkills("searchIndexerSkillset", Arrays.asList("myOcr", "myText")); + // END: com.azure.search.documents.indexes.SearchIndexerClient.resetSkills#String-List + } + + /** + * Code snippet for {@link SearchIndexerClient#resetSkillsWithResponse(SearchIndexerSkillset, List, Context)} + */ + public void resetSkillsWithResponse() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerClient.resetSkillsWithResponse#SearchIndexerSkillset-List-Context + SearchIndexerSkillset searchIndexerSkillset = SEARCH_INDEXER_CLIENT.getSkillset("searchIndexerSkillset"); + + // Reset the "myOcr" and "myText" skills. + Response resetSkillsResponse = SEARCH_INDEXER_CLIENT.resetSkillsWithResponse(searchIndexerSkillset, + Arrays.asList("myOcr", "myText"), new Context(KEY_1, VALUE_1)); + System.out.printf("Resetting skills completed with status code %d.%n", resetSkillsResponse.getStatusCode()); + // END: com.azure.search.documents.indexes.SearchIndexerClient.resetSkillsWithResponse#SearchIndexerSkillset-List-Context + } + + /** + * Code snippet for {@link SearchIndexerAsyncClient#resetSkills(String, List)} + */ + public void resetSkillsAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetSkills#String-List + // Reset the "myOcr" and "myText" skills. + SEARCH_INDEXER_ASYNC_CLIENT.resetSkills("searchIndexerSkillset", Arrays.asList("myOcr", "myText")) + .subscribe(); + // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetSkills#String-List + } + + /** + * Code snippet for {@link SearchIndexerAsyncClient#resetSkillsWithResponse(SearchIndexerSkillset, List)} + */ + public void resetSkillsWithResponseAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetSkillsWithResponse#SearchIndexerSkillset-List + SEARCH_INDEXER_ASYNC_CLIENT.getSkillset("searchIndexerSkillset") + .flatMap(searchIndexerSkillset -> SEARCH_INDEXER_ASYNC_CLIENT.resetSkillsWithResponse(searchIndexerSkillset, + Arrays.asList("myOcr", "myText"))) + .subscribe(resetSkillsResponse -> System.out.printf("Resetting skills completed with status code %d.%n", + resetSkillsResponse.getStatusCode())); + // END: com.azure.search.documents.indexes.SearchIndexerAsyncClient.resetSkillsWithResponse#SearchIndexerSkillset-List + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#createAlias(SearchAlias)}. + */ + public void createAliasAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.createAlias#SearchAlias + SEARCH_INDEX_ASYNC_CLIENT.createAlias(new SearchAlias("my-alias", Collections.singletonList("index-to-alias"))) + .subscribe(searchAlias -> System.out.printf("Created alias '%s' that aliases index '%s'.", + searchAlias.getName(), searchAlias.getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.createAlias#SearchAlias + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#createAliasWithResponse(SearchAlias)}. + */ + public void createAliasWithResponseAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.createAliasWithResponse#SearchAlias + SEARCH_INDEX_ASYNC_CLIENT.createAliasWithResponse(new SearchAlias("my-alias", + Collections.singletonList("index-to-alias"))) + .subscribe(response -> + System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.createAliasWithResponse#SearchAlias + } + + /** + * Code snippet for {@link SearchIndexClient#createAlias(SearchAlias)}. + */ + public void createAlias() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.createAlias#SearchAlias + SearchAlias searchAlias = SEARCH_INDEX_CLIENT.createAlias(new SearchAlias("my-alias", + Collections.singletonList("index-to-alias"))); + System.out.printf("Created alias '%s' that aliases index '%s'.", searchAlias.getName(), + searchAlias.getIndexes().get(0)); + // END: com.azure.search.documents.indexes.SearchIndexClient.createAlias#SearchAlias + } + + /** + * Code snippet for {@link SearchIndexClient#createAliasWithResponse(SearchAlias, Context)}. + */ + public void createAliasWithResponse() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.createAliasWithResponse#SearchAlias-Context + Response response = SEARCH_INDEX_CLIENT.createAliasWithResponse(new SearchAlias("my-alias", + Collections.singletonList("index-to-alias")), new Context(KEY_1, VALUE_1)); + + System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)); + // END: com.azure.search.documents.indexes.SearchIndexClient.createAliasWithResponse#SearchAlias-Context + + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#createOrUpdateAlias(SearchAlias)}. + */ + public void createOrUpdateAliasAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.createOrUpdateAlias#SearchAlias + SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAlias( + new SearchAlias("my-alias", Collections.singletonList("index-to-alias"))) + .flatMap(searchAlias -> { + System.out.printf("Created alias '%s' that aliases index '%s'.", searchAlias.getName(), + searchAlias.getIndexes().get(0)); + + return SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAlias(new SearchAlias(searchAlias.getName(), + Collections.singletonList("new-index-to-alias"))); + }).subscribe(searchAlias -> System.out.printf("Updated alias '%s' to aliases index '%s'.", + searchAlias.getName(), searchAlias.getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.createOrUpdateAlias#SearchAlias + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#createOrUpdateAliasWithResponse(SearchAlias, boolean)}. + */ + public void createOrUpdateAliasWithResponseAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.createOrUpdateAliasWithResponse#SearchAlias-boolean + SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAliasWithResponse( + new SearchAlias("my-alias", Collections.singletonList("index-to-alias")), false) + .flatMap(response -> { + System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)); + + return SEARCH_INDEX_ASYNC_CLIENT.createOrUpdateAliasWithResponse( + new SearchAlias(response.getValue().getName(), Collections.singletonList("new-index-to-alias")) + .setETag(response.getValue().getETag()), true); + }).subscribe(response -> + System.out.printf("Response status code %d. Updated alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.createOrUpdateAliasWithResponse#SearchAlias-boolean + } + + /** + * Code snippet for {@link SearchIndexClient#createOrUpdateAlias(SearchAlias)}. + */ + public void createOrUpdateAlias() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.createOrUpdateAlias#SearchAlias + SearchAlias searchAlias = SEARCH_INDEX_CLIENT.createOrUpdateAlias( + new SearchAlias("my-alias", Collections.singletonList("index-to-alias"))); + + System.out.printf("Created alias '%s' that aliases index '%s'.", searchAlias.getName(), + searchAlias.getIndexes().get(0)); + + searchAlias = SEARCH_INDEX_CLIENT.createOrUpdateAlias(new SearchAlias(searchAlias.getName(), + Collections.singletonList("new-index-to-alias"))); + + System.out.printf("Updated alias '%s' to aliases index '%s'.", searchAlias.getName(), + searchAlias.getIndexes().get(0)); + // END: com.azure.search.documents.indexes.SearchIndexClient.createOrUpdateAlias#SearchAlias + } + + /** + * Code snippet for {@link SearchIndexClient#createOrUpdateAliasWithResponse(SearchAlias, boolean, Context)}. + */ + public void createOrUpdateAliasWithResponse() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.createOrUpdateAliasWithResponse#SearchAlias-boolean-Context + Response response = SEARCH_INDEX_CLIENT.createOrUpdateAliasWithResponse( + new SearchAlias("my-alias", Collections.singletonList("index-to-alias")), false, new Context(KEY_1, VALUE_1)); + + System.out.printf("Response status code %d. Created alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)); + + response = SEARCH_INDEX_CLIENT.createOrUpdateAliasWithResponse( + new SearchAlias(response.getValue().getName(), Collections.singletonList("new-index-to-alias")) + .setETag(response.getValue().getETag()), true, new Context(KEY_1, VALUE_1)); + + System.out.printf("Response status code %d. Updated alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)); + // END: com.azure.search.documents.indexes.SearchIndexClient.createOrUpdateAliasWithResponse#SearchAlias-boolean-Context + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#getAlias(String)}. + */ + public void getAliasAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.getAlias#String + SEARCH_INDEX_ASYNC_CLIENT.getAlias("my-alias") + .subscribe(searchAlias -> System.out.printf("Retrieved alias '%s' that aliases index '%s'.", + searchAlias.getName(), searchAlias.getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.getAlias#String + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#getAliasWithResponse(String)}. + */ + public void getAliasWithResponseAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.getAliasWithResponse#String + SEARCH_INDEX_ASYNC_CLIENT.getAliasWithResponse("my-alias") + .subscribe(response -> + System.out.printf("Response status code %d. Retrieved alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.getAliasWithResponse#String + } + + /** + * Code snippet for {@link SearchIndexClient#getAlias(String)}. + */ + public void getAlias() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.getAlias#String + SearchAlias searchAlias = SEARCH_INDEX_CLIENT.getAlias("my-alias"); + + System.out.printf("Retrieved alias '%s' that aliases index '%s'.", searchAlias.getName(), + searchAlias.getIndexes().get(0)); + // END: com.azure.search.documents.indexes.SearchIndexClient.getAlias#String + } + + /** + * Code snippet for {@link SearchIndexClient#getAliasWithResponse(String, Context)}. + */ + public void getAliasWithResponse() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.getAliasWithResponse#String-Context + Response response = SEARCH_INDEX_CLIENT.getAliasWithResponse("my-alias", new Context(KEY_1, VALUE_1)); + + System.out.printf("Response status code %d. Retrieved alias '%s' that aliases index '%s'.", + response.getStatusCode(), response.getValue().getName(), response.getValue().getIndexes().get(0)); + // END: com.azure.search.documents.indexes.SearchIndexClient.getAliasWithResponse#String-Context + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#deleteAlias(String)}. + */ + public void deleteAliasAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.deleteAlias#String + SEARCH_INDEX_ASYNC_CLIENT.deleteAlias("my-alias") + .subscribe(ignored -> System.out.println("Deleted alias 'my-alias'.")); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.deleteAlias#String + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#deleteAliasWithResponse(SearchAlias, boolean)}. + */ + public void deleteAliasWithResponseAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.deleteAliasWithResponse#SearchAlias-boolean + SEARCH_INDEX_ASYNC_CLIENT.getAlias("my-alias") + .flatMap(searchAlias -> SEARCH_INDEX_ASYNC_CLIENT.deleteAliasWithResponse(searchAlias, true)) + .subscribe(response -> System.out.printf("Response status code %d. Deleted alias 'my-alias'.", + response.getStatusCode())); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.deleteAliasWithResponse#SearchAlias-boolean + } + + /** + * Code snippet for {@link SearchIndexClient#deleteAlias(String)}. + */ + public void deleteAlias() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.deleteAlias#String + SEARCH_INDEX_CLIENT.deleteAlias("my-alias"); + + System.out.println("Deleted alias 'my-alias'."); + // END: com.azure.search.documents.indexes.SearchIndexClient.deleteAlias#String + } + + /** + * Code snippet for {@link SearchIndexClient#deleteAliasWithResponse(SearchAlias, boolean, Context)}. + */ + public void deleteAliasWithResponse() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.deleteAliasWithResponse#SearchAlias-boolean-Context + SearchAlias searchAlias = SEARCH_INDEX_CLIENT.getAlias("my-alias"); + + Response response = SEARCH_INDEX_CLIENT.deleteAliasWithResponse(searchAlias, true, + new Context(KEY_1, VALUE_1)); + + System.out.printf("Response status code %d. Deleted alias 'my-alias'.", response.getStatusCode()); + // END: com.azure.search.documents.indexes.SearchIndexClient.deleteAliasWithResponse#SearchAlias-boolean-Context + } + + /** + * Code snippet for {@link SearchIndexAsyncClient#listAliases()}. + */ + public void listAliasesAsync() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexAsyncClient.listAliases + SEARCH_INDEX_ASYNC_CLIENT.listAliases() + .doOnNext(searchAlias -> System.out.printf("Listed alias '%s' that aliases index '%s'.", + searchAlias.getName(), searchAlias.getIndexes().get(0))) + .subscribe(); + // END: com.azure.search.documents.indexes.SearchIndexAsyncClient.listAliases + } + + /** + * Code snippet for {@link SearchIndexClient#listAliases()}. + */ + public void listAliases() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.listAliases + SEARCH_INDEX_CLIENT.listAliases() + .forEach(searchAlias -> System.out.printf("Listed alias '%s' that aliases index '%s'.", + searchAlias.getName(), searchAlias.getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexClient.listAliases + } + + /** + * Code snippet for {@link SearchIndexClient#listAliases(Context)}. + */ + public void listAliasesWithContext() { + // BEGIN: com.azure.search.documents.indexes.SearchIndexClient.listAliases#Context + SEARCH_INDEX_CLIENT.listAliases(new Context(KEY_1, VALUE_1)) + .forEach(searchAlias -> System.out.printf("Listed alias '%s' that aliases index '%s'.", + searchAlias.getName(), searchAlias.getIndexes().get(0))); + // END: com.azure.search.documents.indexes.SearchIndexClient.listAliases#Context + } } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java new file mode 100644 index 000000000000..9eb262e07f0d --- /dev/null +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java @@ -0,0 +1,374 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.search.documents; + +import com.azure.core.exception.HttpResponseException; +import com.azure.core.test.TestMode; +import com.azure.search.documents.indexes.SearchIndexAsyncClient; +import com.azure.search.documents.indexes.SearchIndexClient; +import com.azure.search.documents.indexes.SearchIndexClientBuilder; +import com.azure.search.documents.indexes.models.SearchAlias; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static com.azure.search.documents.TestHelpers.setupSharedIndex; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Tests {@link SearchAlias}-based operations. + */ +public class SearchAliasTests extends SearchTestBase { + private static final String HOTEL_INDEX_NAME1 = "search-alias-shared-hotel-instance-one"; + private static final String HOTEL_INDEX_NAME2 = "search-alias-shared-hotel-instance-two"; + private static SearchIndexClient searchIndexClient; + + private SearchIndexClient indexClient; + private SearchIndexAsyncClient indexAsyncClient; + + private final List aliasesToDelete = new ArrayList<>(); + + @BeforeAll + public static void beforeAll() { + // When running against the live service ensure all aliases are deleted before running these tests. + if (TEST_MODE == TestMode.PLAYBACK) { + return; // Running in PLAYBACK, no need to clean-up. + } + + searchIndexClient = setupSharedIndex(HOTEL_INDEX_NAME1, HOTELS_TESTS_INDEX_DATA_JSON, null); + setupSharedIndex(HOTEL_INDEX_NAME2, HOTELS_TESTS_INDEX_DATA_JSON, null); + } + + @AfterAll + public static void afterAll() { + if (TEST_MODE != TestMode.PLAYBACK) { + searchIndexClient.deleteIndex(HOTEL_INDEX_NAME1); + searchIndexClient.deleteIndex(HOTEL_INDEX_NAME2); + } + } + + @Override + protected void beforeTest() { + super.beforeTest(); + indexClient = getSearchIndexClientBuilder(true).buildClient(); + indexAsyncClient = getSearchIndexClientBuilder(false).buildAsyncClient(); + } + + @Override + protected void afterTest() { + super.afterTest(); + + // When running against the live service ensure all aliases are deleted before running these tests. + if (TEST_MODE == TestMode.PLAYBACK) { + return; // Running in PLAYBACK, no need to clean-up. + } + + SearchIndexClient cleanupClient = new SearchIndexClientBuilder() + .endpoint(SEARCH_ENDPOINT) + .credential(getTestTokenCredential()) + .buildClient(); + + boolean aliasDeleted = false; + for (String aliasName : aliasesToDelete) { + cleanupClient.deleteAlias(aliasName); + aliasDeleted = true; + } + + if (aliasDeleted) { + // Give 3 seconds for alias deletion to propagate. + sleepIfRunningAgainstService(3000); + } + } + + @Test + public void canCreateAndGetAliasSync() { + SearchAlias expectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + SearchAlias searchAlias = indexClient.createAlias(expectedAlias); + aliasesToDelete.add(searchAlias.getName()); + + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + + searchAlias = indexClient.getAlias(expectedAlias.getName()); + + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + } + + @Test + public void canCreateAliasAsync() { + SearchAlias expectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + + StepVerifier.create(indexAsyncClient.createAlias(expectedAlias)) + .assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + }) + .verifyComplete(); + + StepVerifier.create(indexAsyncClient.getAlias(expectedAlias.getName())) + .assertNext(searchAlias -> { + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + }) + .verifyComplete(); + } + + @Test + public void cannotCreateAliasOnNonExistentIndexSync() { + assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias("my-alias", + Collections.singletonList("index-that-does-not-exist")))); + } + + @Test + public void cannotCreateAliasOnNonExistentIndexAsync() { + StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias("my-alias", + Collections.singletonList("index-that-does-not-exist")))) + .verifyError(HttpResponseException.class); + } + + @Test + public void cannotCreateAliasWithInvalidNameSync() { + assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias("--invalid--alias-name", + Collections.singletonList(HOTEL_INDEX_NAME1)))); + } + + @Test + public void cannotCreateAliasWithInvalidNameAsync() { + StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias("--invalid--alias-name", + Collections.singletonList(HOTEL_INDEX_NAME1)))) + .verifyError(HttpResponseException.class); + } + + @Test + public void cannotCreateMultipleAliasesWithTheSameNameSync() { + SearchAlias expectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + SearchAlias searchAlias = indexClient.createAlias(expectedAlias); + aliasesToDelete.add(searchAlias.getName()); + + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + + assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias(expectedAlias.getName(), + Collections.singletonList(HOTEL_INDEX_NAME1)))); + } + + @Test + public void cannotCreateMultipleAliasesWithTheSameNameAsync() { + SearchAlias expectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + + StepVerifier.create(indexAsyncClient.createAlias(expectedAlias)) + .assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + }) + .verifyComplete(); + + StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias(expectedAlias.getName(), + Collections.singletonList(HOTEL_INDEX_NAME1)))) + .verifyError(HttpResponseException.class); + } + + @Test + public void cannotCreateAliasWithMultipleIndexesSync() { + assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias("my-alias", + Arrays.asList(HOTEL_INDEX_NAME1, HOTEL_INDEX_NAME2)))); + } + + @Test + public void cannotCreateAliasWithMultipleIndexesAsync() { + StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias("my-alias", + Arrays.asList(HOTEL_INDEX_NAME1, HOTEL_INDEX_NAME2)))) + .verifyError(HttpResponseException.class); + } + + @Test + public void canCreateMultipleAliasesReferencingTheSameIndexSync() { + SearchAlias firstExpectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + SearchAlias searchAlias = indexClient.createAlias(firstExpectedAlias); + aliasesToDelete.add(searchAlias.getName()); + + assertEquals(firstExpectedAlias.getName(), searchAlias.getName()); + assertEquals(firstExpectedAlias.getIndexes(), searchAlias.getIndexes()); + + SearchAlias secondExpectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + searchAlias = indexClient.createAlias(secondExpectedAlias); + aliasesToDelete.add(searchAlias.getName()); + + assertEquals(secondExpectedAlias.getName(), searchAlias.getName()); + assertEquals(secondExpectedAlias.getIndexes(), searchAlias.getIndexes()); + } + + @Test + public void canCreateMultipleAliasesReferencingTheSameIndexAsync() { + SearchAlias firstExpectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + + StepVerifier.create(indexAsyncClient.createAlias(firstExpectedAlias)) + .assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(firstExpectedAlias.getName(), searchAlias.getName()); + assertEquals(firstExpectedAlias.getIndexes(), searchAlias.getIndexes()); + }) + .verifyComplete(); + + SearchAlias secondExpectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1)); + + StepVerifier.create(indexAsyncClient.createAlias(secondExpectedAlias)) + .assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(secondExpectedAlias.getName(), searchAlias.getName()); + assertEquals(secondExpectedAlias.getIndexes(), searchAlias.getIndexes()); + }) + .verifyComplete(); + } + + @Test + public void canUpdateAliasAfterCreationSync() { + String aliasName = testResourceNamer.randomName("my-alias", 32); + indexClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))); + aliasesToDelete.add(aliasName); + + SearchAlias expectedUpdatedAlias = new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME2)); + SearchAlias updatedAlias = indexClient.createOrUpdateAlias(expectedUpdatedAlias); + + assertEquals(expectedUpdatedAlias.getName(), updatedAlias.getName()); + assertEquals(expectedUpdatedAlias.getIndexes(), updatedAlias.getIndexes()); + } + + @Test + public void canUpdateAliasAfterCreationAsync() { + String aliasName = testResourceNamer.randomName("my-alias", 32); + indexAsyncClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))) + .block(); + aliasesToDelete.add(aliasName); + + SearchAlias expectedUpdatedAlias = new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME2)); + + StepVerifier.create(indexAsyncClient.createOrUpdateAlias(expectedUpdatedAlias)) + .assertNext(updatedAlias -> { + assertEquals(expectedUpdatedAlias.getName(), updatedAlias.getName()); + assertEquals(expectedUpdatedAlias.getIndexes(), updatedAlias.getIndexes()); + }) + .verifyComplete(); + } + + @Test + public void canDeleteAliasSync() { + String aliasName = testResourceNamer.randomName("my-alias", 32); + indexClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))); + + assertDoesNotThrow(() -> indexClient.deleteAlias(aliasName)); + + // Wait for 1 second for the alias to update + sleepIfRunningAgainstService(1000); + + assertThrows(HttpResponseException.class, () -> indexClient.getIndex(aliasName)); + } + + @Test + public void canDeleteAliasAsync() { + String aliasName = testResourceNamer.randomName("my-alias", 32); + indexAsyncClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))) + .block(); + + StepVerifier.create(indexAsyncClient.deleteAlias(aliasName)).verifyComplete(); + + // Wait for 1 second for the alias to update + sleepIfRunningAgainstService(1000); + + StepVerifier.create(indexAsyncClient.getIndex(aliasName)).verifyError(HttpResponseException.class); + } + + @Test + public void cannotDeleteIndexWithAliasSyncAndAsync() { + String aliasName = testResourceNamer.randomName("my-alias", 32); + indexClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))); + aliasesToDelete.add(aliasName); + + // Give 3 seconds for alias deletion to propagate. + sleepIfRunningAgainstService(3000); + + assertThrows(HttpResponseException.class, () -> indexClient.deleteIndex(HOTEL_INDEX_NAME1)); + assertDoesNotThrow(() -> indexClient.getIndex(HOTEL_INDEX_NAME1)); + + StepVerifier.create(indexAsyncClient.deleteIndex(HOTEL_INDEX_NAME1)) + .verifyError(HttpResponseException.class); + + StepVerifier.create(indexAsyncClient.getIndex(HOTEL_INDEX_NAME1)) + .expectNextCount(1) + .verifyComplete(); + } + + @Test + public void canListAliasesSyncAndAsync() { + String firstAliasName = testResourceNamer.randomName("my-alias", 32); + indexClient.createAlias(new SearchAlias(firstAliasName, + Collections.singletonList(HOTEL_INDEX_NAME1))); + aliasesToDelete.add(firstAliasName); + + String secondAliasName = testResourceNamer.randomName("my-alias", 32); + indexClient.createAlias(new SearchAlias(secondAliasName, + Collections.singletonList(HOTEL_INDEX_NAME1))); + aliasesToDelete.add(secondAliasName); + + String thirdAliasName = testResourceNamer.randomName("my-alias", 32); + indexClient.createAlias(new SearchAlias(thirdAliasName, + Collections.singletonList(HOTEL_INDEX_NAME1))); + aliasesToDelete.add(thirdAliasName); + + List syncAliases = indexClient.listAliases().stream().collect(Collectors.toList()); + assertEquals(3, syncAliases.size()); + assertTrue(syncAliases.stream().anyMatch(alias -> alias.getName().equals(firstAliasName))); + assertTrue(syncAliases.stream().anyMatch(alias -> alias.getName().equals(secondAliasName))); + assertTrue(syncAliases.stream().anyMatch(alias -> alias.getName().equals(thirdAliasName))); + + StepVerifier.create(indexAsyncClient.listAliases().collectList()) + .assertNext(asyncAliases -> { + assertEquals(3, asyncAliases.size()); + assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(firstAliasName))); + assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(secondAliasName))); + assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(thirdAliasName))); + }) + .verifyComplete(); + } + + @Test + public void canInspectAliasUsageInServiceStatisticsSyncAndAsync() { + aliasesToDelete.add(indexClient.createAlias(new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1))).getName()); + aliasesToDelete.add(indexClient.createAlias(new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1))).getName()); + aliasesToDelete.add(indexClient.createAlias(new SearchAlias(testResourceNamer.randomName("my-alias", 32), + Collections.singletonList(HOTEL_INDEX_NAME1))).getName()); + + // Give 3 seconds for alias creation to propagate. + sleepIfRunningAgainstService(3000); + + assertEquals(3, indexClient.getServiceStatistics().getCounters().getAliasCounter().getUsage()); + + StepVerifier.create(indexAsyncClient.getServiceStatistics()) + .assertNext(serviceStatistics -> assertEquals(3, + serviceStatistics.getCounters().getAliasCounter().getUsage())) + .verifyComplete(); + } +} diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java index 0db4f8045f47..cf7534b5bd45 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java @@ -5,6 +5,7 @@ import com.azure.core.models.GeoPoint; import com.azure.search.documents.TestHelpers; +import com.azure.search.documents.indexes.models.LexicalNormalizerName; import com.azure.search.documents.indexes.models.SearchField; import com.azure.search.documents.indexes.models.SearchFieldDataType; import com.azure.search.documents.test.environment.models.HotelAnalyzerException; @@ -19,6 +20,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.time.OffsetDateTime; import java.util.Arrays; @@ -332,6 +335,43 @@ public List getByteList() { } } + @Test + public void validNormalizerField() { + List fields = SearchIndexClient.buildSearchFields(ValidNormalizer.class, null); + + assertEquals(1, fields.size()); + + SearchField normalizerField = fields.get(0); + assertEquals(LexicalNormalizerName.STANDARD, normalizerField.getNormalizerName()); + } + + @SuppressWarnings("unused") + public static final class ValidNormalizer { + @SimpleField(normalizerName = "standard", isFilterable = true) + public String validNormalizer; + } + + @ParameterizedTest + @ValueSource(classes = { NonStringNormalizer.class, MissingFunctionalityNormalizer.class }) + public void invalidNormalizerField(Class type) { + RuntimeException ex = assertThrows(RuntimeException.class, + () -> SearchIndexClient.buildSearchFields(type, null)); + + assertTrue(ex.getMessage().contains("A field with a normalizer name")); + } + + @SuppressWarnings("unused") + public static final class NonStringNormalizer { + @SimpleField(normalizerName = "standard") + public int wrongTypeForNormalizer; + } + + @SuppressWarnings("unused") + public static final class MissingFunctionalityNormalizer { + @SimpleField(normalizerName = "standard") + public String rightTypeWrongFunctionality; + } + @Test public void onlyAnalyzerNameSetsOnlyAnalyzerName() { List fields = SearchIndexClient.buildSearchFields(OnlyAnalyzerName.class, null); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/NonRestCallTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/NonRestCallTests.java index 763849746ae6..8c4660e0a8a2 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/NonRestCallTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/NonRestCallTests.java @@ -35,12 +35,14 @@ static Stream> apiCallReturnsErrorSupplier() { return Stream.of(client.createOrUpdateDataSourceConnection(null), client.createOrUpdateDataSourceConnectionWithResponse(null, true), + client.createOrUpdateDataSourceConnectionWithResponse(null), client.deleteDataSourceConnectionWithResponse(null, true), client.createOrUpdateIndexer(null), client.createOrUpdateIndexerWithResponse(null, true), - client.deleteIndexerWithResponse(null, true), + client.createOrUpdateIndexerWithResponse(null), client.deleteIndexerWithResponse(null, true), client.createSkillset(null), client.createSkillsetWithResponse(null), client.createOrUpdateSkillset(null), - client.createOrUpdateSkillsetWithResponse(null, true), client.deleteSkillsetWithResponse(null, true)); + client.createOrUpdateSkillsetWithResponse(null, true), client.createOrUpdateSkillsetWithResponse(null), + client.deleteSkillsetWithResponse(null, true)); } } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java new file mode 100644 index 000000000000..020b44eda983 --- /dev/null +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java @@ -0,0 +1,118 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.search.documents.indexes; + +import com.azure.search.documents.indexes.models.BlobIndexerDataToExtract; +import com.azure.search.documents.indexes.models.BlobIndexerImageAction; +import com.azure.search.documents.indexes.models.BlobIndexerParsingMode; +import com.azure.search.documents.indexes.models.BlobIndexerPdfTextRotationAlgorithm; +import com.azure.search.documents.indexes.models.CreateOrUpdateDataSourceConnectionOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateIndexerOptions; +import com.azure.search.documents.indexes.models.CreateOrUpdateSkillsetOptions; +import com.azure.search.documents.indexes.models.IndexerExecutionEnvironment; +import com.azure.search.documents.indexes.models.IndexingParameters; +import com.azure.search.documents.indexes.models.IndexingParametersConfiguration; +import com.azure.search.documents.indexes.models.SearchIndexer; +import com.azure.search.documents.indexes.models.SearchIndexerDataSourceConnection; +import com.azure.search.documents.indexes.models.SearchIndexerSkillset; +import org.junit.jupiter.api.function.Executable; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@Execution(ExecutionMode.CONCURRENT) +public class OptionBagsTests { + private static final Map FOOL_SPOTBUGS = new HashMap<>(); + + @ParameterizedTest + @MethodSource("nullRequiredValuesThrowNullPointerExceptionsSupplier") + public void nullRequiredValuesThrowNullPointerExceptions(Executable constructorCallWithNullParameter) { + assertThrows(NullPointerException.class, constructorCallWithNullParameter); + } + + static Stream nullRequiredValuesThrowNullPointerExceptionsSupplier() { + return Stream.of( + () -> new CreateOrUpdateDataSourceConnectionOptions((SearchIndexerDataSourceConnection) + FOOL_SPOTBUGS.get("value")), + () -> new CreateOrUpdateIndexerOptions((SearchIndexer) FOOL_SPOTBUGS.get("value")), + () -> new CreateOrUpdateSkillsetOptions((SearchIndexerSkillset) FOOL_SPOTBUGS.get("value")) + ); + } + + @ParameterizedTest + @MethodSource("getIndexingParametersConfigurationSupplier") + public void getIndexingParametersConfiguration(Map configuration, + Function parameterGetter, Object expected) { + IndexingParametersConfiguration indexingParametersConfiguration = new IndexingParameters() + .setConfiguration(configuration) + .getIndexingParametersConfiguration(); + + assertEquals(expected, parameterGetter.apply(indexingParametersConfiguration)); + } + + static Stream getIndexingParametersConfigurationSupplier() { + return Stream.of( + createArguments("parsingMode", BlobIndexerParsingMode.DEFAULT, + IndexingParametersConfiguration::getParsingMode), + + createArguments("excludedFileNameExtensions", "parquet", + IndexingParametersConfiguration::getExcludedFileNameExtensions), + + createArguments("indexedFileNameExtensions", "json", + IndexingParametersConfiguration::getIndexedFileNameExtensions), + + createArguments("failOnUnsupportedContentType", true, + IndexingParametersConfiguration::isFailOnUnsupportedContentType), + + createArguments("failOnUnprocessableDocument", true, + IndexingParametersConfiguration::isFailOnUnprocessableDocument), + + createArguments("indexStorageMetadataOnlyForOversizedDocuments", true, + IndexingParametersConfiguration::isIndexStorageMetadataOnlyForOversizedDocuments), + + createArguments("delimitedTextHeaders", "headers", + IndexingParametersConfiguration::getDelimitedTextHeaders), + + createArguments("delimitedTextDelimiter", ",", IndexingParametersConfiguration::getDelimitedTextDelimiter), + + createArguments("firstLineContainsHeaders", true, + IndexingParametersConfiguration::isFirstLineContainsHeaders), + + createArguments("documentRoot", "/", IndexingParametersConfiguration::getDocumentRoot), + + createArguments("dataToExtract", BlobIndexerDataToExtract.CONTENT_AND_METADATA, + IndexingParametersConfiguration::getDataToExtract), + + createArguments("imageAction", BlobIndexerImageAction.GENERATE_NORMALIZED_IMAGE_PER_PAGE, + IndexingParametersConfiguration::getImageAction), + + createArguments("allowSkillsetToReadFileData", true, + IndexingParametersConfiguration::isAllowSkillsetToReadFileData), + + createArguments("pdfTextRotationAlgorithm", BlobIndexerPdfTextRotationAlgorithm.DETECT_ANGLES, + IndexingParametersConfiguration::getPdfTextRotationAlgorithm), + + createArguments("executionEnvironment", IndexerExecutionEnvironment.STANDARD, + IndexingParametersConfiguration::getExecutionEnvironment), + + createArguments("queryTimeout", "1:00:00", IndexingParametersConfiguration::getQueryTimeout) + ); + } + + static Arguments createArguments(String key, Object expected, + Function getter) { + return Arguments.of(Collections.singletonMap(key, expected), getter, expected); + } +} diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java index 5e39a9edd430..ee766cf1b769 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java @@ -19,6 +19,7 @@ import com.azure.search.documents.indexes.SearchIndexerClient; import com.azure.search.documents.indexes.SearchIndexerClientBuilder; import com.azure.search.documents.indexes.models.IndexDocumentsBatch; +import com.azure.search.documents.indexes.models.SearchAlias; import com.azure.search.documents.indexes.models.SearchIndex; import com.azure.search.documents.indexes.models.SearchIndexer; import com.azure.search.documents.indexes.models.SearchIndexerDataSourceConnection; @@ -38,6 +39,7 @@ import java.util.function.Supplier; import java.util.stream.Stream; +import static java.util.Collections.emptyList; import static org.junit.jupiter.api.Assertions.assertTrue; @Execution(ExecutionMode.CONCURRENT) @@ -93,6 +95,9 @@ public static Stream correctUrlRewriteSupplier() { SynonymMap synonymMap = new SynonymMap("synonym"); String synonymMapUrl = "https://test.search.windows.net/synonymmaps/synonym"; + SearchAlias alias = new SearchAlias("alias", emptyList()); + String aliasUrl = "https://test.search.windows.net/aliases/alias"; + SearchIndexerDataSourceConnection dataSource = new SearchIndexerDataSourceConnection("datasource"); String dataSourceUrl = "https://test.search.windows.net/datasources/datasource"; @@ -167,6 +172,16 @@ public static Stream correctUrlRewriteSupplier() { Arguments.of(toCallable(() -> searchIndexClient.getServiceStatisticsWithResponse(Context.NONE)), "https://test.search.windows.net/servicestats"), + Arguments.of(toCallable(() -> searchIndexClient.createAliasWithResponse(alias, Context.NONE)), + "https://test.search.windows.net/aliases"), + Arguments.of(toCallable(() -> searchIndexClient.createOrUpdateAliasWithResponse(alias, false, + Context.NONE)), aliasUrl), + Arguments.of(toCallable(() -> searchIndexClient.getAliasWithResponse("alias", Context.NONE)), aliasUrl), + Arguments.of(toCallable(() -> searchIndexClient.deleteAliasWithResponse(alias, true, Context.NONE)), + aliasUrl), + Arguments.of(toCallable(() -> searchIndexClient.listAliases(Context.NONE).iterator().hasNext()), + "https://test.search.windows.net/aliases"), + Arguments.of(toCallable(searchIndexAsyncClient.createIndexWithResponse(index)), "https://test.search.windows.net/indexes"), Arguments.of(toCallable(searchIndexAsyncClient.getIndexWithResponse("index")), indexUrl), @@ -192,6 +207,15 @@ public static Stream correctUrlRewriteSupplier() { synonymMapUrl), Arguments.of(toCallable(searchIndexAsyncClient.getServiceStatisticsWithResponse()), "https://test.search.windows.net/servicestats"), + Arguments.of(toCallable(() -> searchIndexClient.createAliasWithResponse(alias, Context.NONE)), + "https://test.search.windows.net/aliases"), + Arguments.of(toCallable(() -> searchIndexClient.createOrUpdateAliasWithResponse(alias, false, + Context.NONE)), aliasUrl), + Arguments.of(toCallable(() -> searchIndexClient.getAliasWithResponse("alias", Context.NONE)), aliasUrl), + Arguments.of(toCallable(() -> searchIndexClient.deleteAliasWithResponse(alias, true, Context.NONE)), + aliasUrl), + Arguments.of(toCallable(() -> searchIndexClient.listAliases(Context.NONE).iterator().hasNext()), + "https://test.search.windows.net/aliases"), Arguments.of(toCallable(() -> searchIndexerClient.createOrUpdateDataSourceConnectionWithResponse(dataSource, true, Context.NONE)), dataSourceUrl), Arguments.of( @@ -229,6 +253,8 @@ public static Stream correctUrlRewriteSupplier() { indexerUrl + "/search.run"), Arguments.of(toCallable(() -> searchIndexerClient.getIndexerStatusWithResponse("indexer", Context.NONE)), indexerUrl + "/search.status"), + Arguments.of(toCallable(() -> searchIndexerClient.resetDocumentsWithResponse(indexer, null, emptyList(), + emptyList(), Context.NONE)), indexerUrl + "/search.resetdocs"), Arguments.of(toCallable(() -> searchIndexerClient.createSkillsetWithResponse(skillset, Context.NONE)), "https://test.search.windows.net/skillsets"), Arguments.of(toCallable(() -> searchIndexerClient.getSkillsetWithResponse("skillset", Context.NONE)), @@ -242,6 +268,8 @@ public static Stream correctUrlRewriteSupplier() { skillsetUrl), Arguments.of(toCallable(() -> searchIndexerClient.deleteSkillsetWithResponse(skillset, true, Context.NONE)), skillsetUrl), + Arguments.of(toCallable(() -> searchIndexerClient.resetSkillsWithResponse(skillset, emptyList(), + Context.NONE)), skillsetUrl + "/search.resetskills"), Arguments.of( toCallable(searchIndexerAsyncClient.createOrUpdateDataSourceConnectionWithResponse(dataSource, true)), @@ -272,6 +300,8 @@ public static Stream correctUrlRewriteSupplier() { indexerUrl + "/search.run"), Arguments.of(toCallable(searchIndexerAsyncClient.getIndexerStatusWithResponse("indexer")), indexerUrl + "/search.status"), + Arguments.of(toCallable(searchIndexerAsyncClient.resetDocumentsWithResponse(indexer, null, emptyList(), + emptyList())), indexerUrl + "/search.resetdocs"), Arguments.of(toCallable(searchIndexerAsyncClient.createSkillsetWithResponse(skillset)), "https://test.search.windows.net/skillsets"), Arguments.of(toCallable(searchIndexerAsyncClient.getSkillsetWithResponse("skillset")), skillsetUrl), @@ -282,7 +312,8 @@ public static Stream correctUrlRewriteSupplier() { Arguments.of(toCallable(searchIndexerAsyncClient.createOrUpdateSkillsetWithResponse(skillset, false)), skillsetUrl), Arguments.of(toCallable(searchIndexerAsyncClient.deleteSkillsetWithResponse(skillset, true)), skillsetUrl), - Arguments.of(toCallable(searchIndexerAsyncClient.deleteSkillsetWithResponse(skillset, true)), skillsetUrl)); + Arguments.of(toCallable(searchIndexerAsyncClient.resetSkillsWithResponse(skillset, emptyList())), + skillsetUrl + "/search.resetskills")); } private static Callable toCallable(Supplier apiCall) { diff --git a/sdk/search/azure-search-documents/swagger/README.md b/sdk/search/azure-search-documents/swagger/README.md index 8336a868c431..a8719a6a5edf 100644 --- a/sdk/search/azure-search-documents/swagger/README.md +++ b/sdk/search/azure-search-documents/swagger/README.md @@ -22,8 +22,8 @@ npm install -g autorest ### Generation -There are two swaggers for Azure Search, `searchindex` and `searchservice`. They always under same package version, e.g. -`--tag=searchindex` and `--tag=searchservice`. +There are three swaggers for Azure Search, `searchindex`, `searchservice`, and `knowledgeagent`. They always under same +package version, e.g. `--tag=searchindex`, `--tag=searchservice`, and `--tag=knowledgeagent`. ```ps cd @@ -35,6 +35,7 @@ e.g. cd autorest --tag=searchindex autorest --tag=searchservice +autorest --tag=knowledgeagent ``` ## Manual Changes @@ -87,7 +88,7 @@ These settings apply only when `--tag=searchindex` is specified on the command l ``` yaml $(tag) == 'searchindex' namespace: com.azure.search.documents input-file: -- https://raw.githubusercontent.com/Azure/azure-rest-api-specs/e078973418d713e01edf3585f95d3378fc6f67c8/specification/search/data-plane/Azure.Search/preview/2025-08-01-preview/searchindex.json +- https://raw.githubusercontent.com/Azure/azure-rest-api-specs/429fd8c039c5b08541df2389f8c58d1090e01127/specification/search/data-plane/Azure.Search/preview/2025-08-01-preview/searchindex.json models-subpackage: models custom-types-subpackage: implementation.models custom-types: AutocompleteRequest,IndexAction,IndexBatch,RequestOptions,SearchDocumentsResult,SearchErrorException,SearchOptions,SearchRequest,SearchResult,SuggestDocumentsResult,SuggestRequest,SuggestResult,ErrorAdditionalInfo,ErrorDetail,ErrorResponse,ErrorResponseException,Speller @@ -105,7 +106,7 @@ These settings apply only when `--tag=searchservice` is specified on the command ``` yaml $(tag) == 'searchservice' namespace: com.azure.search.documents.indexes input-file: -- https://raw.githubusercontent.com/Azure/azure-rest-api-specs/e078973418d713e01edf3585f95d3378fc6f67c8/specification/search/data-plane/Azure.Search/preview/2025-08-01-preview/searchservice.json +- https://raw.githubusercontent.com/Azure/azure-rest-api-specs/429fd8c039c5b08541df2389f8c58d1090e01127/specification/search/data-plane/Azure.Search/preview/2025-08-01-preview/searchservice.json models-subpackage: models custom-types-subpackage: implementation.models custom-types: AnalyzeRequest,AnalyzeResult,AzureActiveDirectoryApplicationCredentials,DataSourceCredentials,DocumentKeysOrIds,EdgeNGramTokenFilterV1,EdgeNGramTokenFilterV2,EntityRecognitionSkillV1,EntityRecognitionSkillV3,KeywordTokenizerV1,KeywordTokenizerV2,ListAliasesResult,ListDataSourcesResult,ListIndexersResult,ListIndexesResult,ListIndexStatsSummary,ListKnowledgeAgentsResult,ListKnowledgeSourcesResult,ListSkillsetsResult,ListSynonymMapsResult,LuceneStandardTokenizerV1,LuceneStandardTokenizerV2,NGramTokenFilterV1,NGramTokenFilterV2,RequestOptions,SearchErrorException,SentimentSkillV1,SentimentSkillV3,SkillNames,ErrorAdditionalInfo,ErrorDetail,ErrorResponse,ErrorResponseException @@ -162,7 +163,7 @@ These settings apply only when `--tag=knowledgeagent` is specified on the comman ``` yaml $(tag) == 'knowledgeagent' namespace: com.azure.search.documents.agents input-file: -- https://raw.githubusercontent.com/Azure/azure-rest-api-specs/e078973418d713e01edf3585f95d3378fc6f67c8/specification/search/data-plane/Azure.Search/preview/2025-08-01-preview/knowledgeagent.json +- https://raw.githubusercontent.com/Azure/azure-rest-api-specs/429fd8c039c5b08541df2389f8c58d1090e01127/specification/search/data-plane/Azure.Search/preview/2025-08-01-preview/knowledgeagent.json models-subpackage: models custom-types-subpackage: implementation.models custom-types: ErrorResponse,ErrorDetail,ErrorAdditionalInfo,ErrorResponseException,RequestOptions @@ -279,6 +280,7 @@ directive: $.analyzer["x-ms-client-name"] = "analyzerName"; $.searchAnalyzer["x-ms-client-name"] = "searchAnalyzerName"; $.indexAnalyzer["x-ms-client-name"] = "indexAnalyzerName"; + $.normalizer["x-ms-client-name"] = "normalizerName"; $.synonymMaps["x-ms-client-name"] = "synonymMapNames"; ``` From 2d0a15a3649cfcc01e2ea579b93ef9971e3c766a Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Tue, 2 Sep 2025 12:07:47 -0400 Subject: [PATCH 11/12] Update tests to handle deployment supplied data --- sdk/search/azure-search-documents/assets.json | 2 +- .../search/documents/SearchAsyncClient.java | 32 +--- .../models/WebKnowledgeSourceParams.java | 131 -------------- .../indexes/SearchIndexAsyncClient.java | 12 +- .../documents/indexes/SearchIndexClient.java | 14 +- .../indexes/SearchIndexerAsyncClient.java | 35 ++-- .../indexes/SearchIndexerClient.java | 19 +- ...teOrUpdateDataSourceConnectionOptions.java | 7 +- .../models/CreateOrUpdateIndexerOptions.java | 4 +- .../models/CreateOrUpdateSkillsetOptions.java | 4 +- .../search/documents/SearchAliasTests.java | 162 ++++++++---------- .../search/documents/VectorSearchTests.java | 18 +- .../indexes/FieldBuilderServiceTests.java | 1 - .../documents/indexes/FieldBuilderTests.java | 4 +- .../indexes/IndexManagementTests.java | 42 ++--- .../documents/indexes/OptionBagsTests.java | 15 +- .../SearchIndexClientBuilderTests.java | 3 +- .../SearchIndexerClientBuilderTests.java | 3 +- .../SearchRequestUrlRewriterPolicyTests.java | 21 ++- 19 files changed, 181 insertions(+), 348 deletions(-) delete mode 100644 sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java diff --git a/sdk/search/azure-search-documents/assets.json b/sdk/search/azure-search-documents/assets.json index 25de395cc455..feefa2ff2211 100644 --- a/sdk/search/azure-search-documents/assets.json +++ b/sdk/search/azure-search-documents/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "java", "TagPrefix": "java/search/azure-search-documents", - "Tag": "java/search/azure-search-documents_93e02a04a0" + "Tag": "java/search/azure-search-documents_b2580498bd" } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchAsyncClient.java index 81a9f4ecad30..cd157da66932 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/SearchAsyncClient.java @@ -1069,12 +1069,8 @@ Mono> getDocumentCountWithResponse(Context context) { * AtomicLong numberOfDocumentsReturned = new AtomicLong(); * searchPagedFlux.byPage() * .takeUntil(page -> { - * if (numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT) { - * // Reached the $skip limit, stop requesting more documents. - * return true; - * } - * - * return false; + * // Reached the $skip limit, stop requesting more documents. + * return numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT; * }) * .subscribe(resultResponse -> { * for (SearchResult result: resultResponse.getValue()) { @@ -1126,12 +1122,8 @@ public SearchPagedFlux search(String searchText) { * AtomicLong numberOfDocumentsReturned = new AtomicLong(); * searchPagedFlux.byPage() * .takeUntil(page -> { - * if (numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT) { - * // Reached the $skip limit, stop requesting more documents. - * return true; - * } - * - * return false; + * // Reached the $skip limit, stop requesting more documents. + * return numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT; * }) * .subscribe(resultResponse -> { * for (SearchResult result: resultResponse.getValue()) { @@ -1186,12 +1178,8 @@ public SearchPagedFlux search(String searchText, String querySourceAuthorization * AtomicLong numberOfDocumentsReturned = new AtomicLong(); * pagedFlux.byPage() * .takeUntil(page -> { - * if (numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT) { - * // Reached the $skip limit, stop requesting more documents. - * return true; - * } - * - * return false; + * // Reached the $skip limit, stop requesting more documents. + * return numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT; * }) * .subscribe(searchResultResponse -> searchResultResponse.getValue().forEach(searchDocument -> { * for (Map.Entry<String, Object> keyValuePair @@ -1244,12 +1232,8 @@ public SearchPagedFlux search(String searchText, SearchOptions searchOptions) { * AtomicLong numberOfDocumentsReturned = new AtomicLong(); * pagedFlux.byPage() * .takeUntil(page -> { - * if (numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT) { - * // Reached the $skip limit, stop requesting more documents. - * return true; - * } - * - * return false; + * // Reached the $skip limit, stop requesting more documents. + * return numberOfDocumentsReturned.addAndGet(page.getValue().size()) >= SEARCH_SKIP_LIMIT; * }) * .subscribe(searchResultResponse -> searchResultResponse.getValue().forEach(searchDocument -> { * for (Map.Entry<String, Object> keyValuePair diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java deleted file mode 100644 index b1b6dd42b7b1..000000000000 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/agents/models/WebKnowledgeSourceParams.java +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -package com.azure.search.documents.agents.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Specifies runtime parameters for a web knowledge source. - */ -@Fluent -public final class WebKnowledgeSourceParams extends KnowledgeSourceParams { - /* - * The type of the knowledge source. - */ - @Generated - private KnowledgeSourceKind kind = KnowledgeSourceKind.WEB; - - /* - * The freshness of web results. - */ - @Generated - private String freshness; - - /** - * Creates an instance of WebKnowledgeSourceParams class. - * - * @param knowledgeSourceName the knowledgeSourceName value to set. - */ - @Generated - public WebKnowledgeSourceParams(String knowledgeSourceName) { - super(knowledgeSourceName); - } - - /** - * Get the kind property: The type of the knowledge source. - * - * @return the kind value. - */ - @Generated - @Override - public KnowledgeSourceKind getKind() { - return this.kind; - } - - /** - * Get the freshness property: The freshness of web results. - * - * @return the freshness value. - */ - @Generated - public String getFreshness() { - return this.freshness; - } - - /** - * Set the freshness property: The freshness of web results. - * - * @param freshness the freshness value to set. - * @return the WebKnowledgeSourceParams object itself. - */ - @Generated - public WebKnowledgeSourceParams setFreshness(String freshness) { - this.freshness = freshness; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("knowledgeSourceName", getKnowledgeSourceName()); - jsonWriter.writeStringField("kind", this.kind == null ? null : this.kind.toString()); - jsonWriter.writeStringField("freshness", this.freshness); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of WebKnowledgeSourceParams from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of WebKnowledgeSourceParams if the JsonReader was pointing to an instance of it, or null if - * it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the WebKnowledgeSourceParams. - */ - @Generated - public static WebKnowledgeSourceParams fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - boolean knowledgeSourceNameFound = false; - String knowledgeSourceName = null; - KnowledgeSourceKind kind = KnowledgeSourceKind.WEB; - String freshness = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - - if ("knowledgeSourceName".equals(fieldName)) { - knowledgeSourceName = reader.getString(); - knowledgeSourceNameFound = true; - } else if ("kind".equals(fieldName)) { - kind = KnowledgeSourceKind.fromString(reader.getString()); - } else if ("freshness".equals(fieldName)) { - freshness = reader.getString(); - } else { - reader.skipChildren(); - } - } - if (knowledgeSourceNameFound) { - WebKnowledgeSourceParams deserializedWebKnowledgeSourceParams - = new WebKnowledgeSourceParams(knowledgeSourceName); - deserializedWebKnowledgeSourceParams.kind = kind; - deserializedWebKnowledgeSourceParams.freshness = freshness; - - return deserializedWebKnowledgeSourceParams; - } - throw new IllegalStateException("Missing required property: knowledgeSourceName"); - }); - } -} diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java index 667c5b21f888..4ca596caf885 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java @@ -1388,14 +1388,14 @@ public Mono> createOrUpdateAliasWithResponse(SearchAlias a return monoError(LOGGER, new NullPointerException("'alias' cannot be null.")); } - return withContext(context -> createOrUpdateAliasWithResponse(alias, - onlyIfUnchanged ? alias.getETag() : null, context)); + return withContext( + context -> createOrUpdateAliasWithResponse(alias, onlyIfUnchanged ? alias.getETag() : null, context)); } Mono> createOrUpdateAliasWithResponse(SearchAlias alias, String eTag, Context context) { try { - return restClient.getAliases().createOrUpdateWithResponseAsync(alias.getName(), alias, eTag, null, null, - context); + return restClient.getAliases() + .createOrUpdateWithResponseAsync(alias.getName(), alias, eTag, null, null, context); } catch (RuntimeException ex) { return monoError(LOGGER, ex); } @@ -1500,8 +1500,8 @@ public Mono> deleteAliasWithResponse(SearchAlias alias, boolean o return monoError(LOGGER, new NullPointerException("'alias' cannot be null.")); } - return withContext(context -> deleteAliasWithResponse(alias.getName(), onlyIfUnchanged ? alias.getETag() : null, - context)); + return withContext( + context -> deleteAliasWithResponse(alias.getName(), onlyIfUnchanged ? alias.getETag() : null, context)); } Mono> deleteAliasWithResponse(String aliasName, String eTag, Context context) { diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java index 78558d1fa3a7..ee36c49b268d 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexClient.java @@ -1429,7 +1429,8 @@ public Response createOrUpdateAliasWithResponse(SearchAlias alias, Context context) { return Utility.executeRestCallWithExceptionHandling(() -> restClient.getAliases() .createOrUpdateWithResponse(alias.getName(), alias, onlyIfUnchanged ? alias.getETag() : null, null, null, - context), LOGGER); + context), + LOGGER); } /** @@ -1476,8 +1477,8 @@ public SearchAlias getAlias(String aliasName) { * @return the retrieved alias. */ public Response getAliasWithResponse(String aliasName, Context context) { - return Utility.executeRestCallWithExceptionHandling(() -> restClient.getAliases() - .getWithResponse(aliasName, null, context), LOGGER); + return Utility.executeRestCallWithExceptionHandling( + () -> restClient.getAliases().getWithResponse(aliasName, null, context), LOGGER); } /** @@ -1529,8 +1530,8 @@ public Response deleteAliasWithResponse(SearchAlias alias, boolean onlyIfU } Response deleteAliasWithResponse(String aliasName, String eTag, Context context) { - return Utility.executeRestCallWithExceptionHandling(() -> restClient.getAliases() - .deleteWithResponse(aliasName, eTag, null, null, context), LOGGER); + return Utility.executeRestCallWithExceptionHandling( + () -> restClient.getAliases().deleteWithResponse(aliasName, eTag, null, null, context), LOGGER); } /** @@ -1574,8 +1575,7 @@ public PagedIterable listAliases() { */ public PagedIterable listAliases(Context context) { try { - return new PagedIterable<>(() -> restClient.getAliases() - .listSinglePage(null, context)); + return new PagedIterable<>(() -> restClient.getAliases().listSinglePage(null, context)); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java index 8032322e09ba..6a287165dae9 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerAsyncClient.java @@ -539,8 +539,8 @@ public Mono> createOrUpdateDataSourc * @throws NullPointerException If {@code options} is null. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> createOrUpdateDataSourceConnectionWithResponse( - CreateOrUpdateDataSourceConnectionOptions options) { + public Mono> + createOrUpdateDataSourceConnectionWithResponse(CreateOrUpdateDataSourceConnectionOptions options) { if (options == null) { return monoError(LOGGER, new NullPointerException("'options' cannot be null.")); } @@ -1011,10 +1011,9 @@ public Mono> createOrUpdateIndexerWithResponse(CreateOrU return monoError(LOGGER, new NullPointerException("'options' cannot be null.")); } - return withContext( - context -> createOrUpdateIndexerWithResponse(options.getIndexer(), options.isOnlyIfUnchanged(), - options.isCacheReprocessingChangeDetectionDisabled(), options.isCacheResetRequirementsIgnored(), - context)); + return withContext(context -> createOrUpdateIndexerWithResponse(options.getIndexer(), + options.isOnlyIfUnchanged(), options.isCacheReprocessingChangeDetectionDisabled(), + options.isCacheResetRequirementsIgnored(), context)); } Mono> createOrUpdateIndexerWithResponse(SearchIndexer indexer, boolean onlyIfUnchanged, @@ -1421,7 +1420,7 @@ public Mono resetDocuments(String indexerName, Boolean overwrite, List datasourceDocumentIds) { return withContext( context -> resetDocumentsWithResponse(indexerName, overwrite, documentKeys, datasourceDocumentIds, context)) - .map(Response::getValue); + .map(Response::getValue); } /** @@ -1465,15 +1464,15 @@ public Mono> resetDocumentsWithResponse(SearchIndexer indexer, Bo return monoError(LOGGER, new NullPointerException("'indexer' cannot be null.")); } - return withContext(context -> - resetDocumentsWithResponse(indexer.getName(), overwrite, documentKeys, datasourceDocumentIds, context)); + return withContext(context -> resetDocumentsWithResponse(indexer.getName(), overwrite, documentKeys, + datasourceDocumentIds, context)); } Mono> resetDocumentsWithResponse(String indexerName, Boolean overwrite, List documentKeys, List datasourceDocumentIds, Context context) { try { - DocumentKeysOrIds documentKeysOrIds = new DocumentKeysOrIds().setDocumentKeys(documentKeys) - .setDatasourceDocumentIds(datasourceDocumentIds); + DocumentKeysOrIds documentKeysOrIds + = new DocumentKeysOrIds().setDocumentKeys(documentKeys).setDatasourceDocumentIds(datasourceDocumentIds); return restClient.getIndexers() .resetDocsWithResponseAsync(indexerName, overwrite, documentKeysOrIds, null, context); @@ -1804,16 +1803,15 @@ public Mono> createOrUpdateSkillsetWithResponse( * @throws NullPointerException If {@code options} is null. */ @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> createOrUpdateSkillsetWithResponse( - CreateOrUpdateSkillsetOptions options) { + public Mono> + createOrUpdateSkillsetWithResponse(CreateOrUpdateSkillsetOptions options) { if (options == null) { return monoError(LOGGER, new NullPointerException("'options' cannot be null.")); } - return withContext( - context -> createOrUpdateSkillsetWithResponse(options.getSkillset(), options.isOnlyIfUnchanged(), - options.isCacheReprocessingChangeDetectionDisabled(), - options.isCacheResetRequirementsIgnored(), context)); + return withContext(context -> createOrUpdateSkillsetWithResponse(options.getSkillset(), + options.isOnlyIfUnchanged(), options.isCacheReprocessingChangeDetectionDisabled(), + options.isCacheResetRequirementsIgnored(), context)); } Mono> createOrUpdateSkillsetWithResponse(SearchIndexerSkillset skillset, @@ -1960,7 +1958,8 @@ Mono> resyncWithResponseAsync(String indexerName, IndexerResyncBo */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono resetSkills(String skillsetName, List skillNames) { - return withContext(context -> resetSkillsWithResponse(skillsetName, skillNames, context).flatMap(FluxUtil::toMono)); + return withContext( + context -> resetSkillsWithResponse(skillsetName, skillNames, context).flatMap(FluxUtil::toMono)); } /** diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java index 4f406f3393a7..6902704d7cfd 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexerClient.java @@ -1514,8 +1514,7 @@ public PagedIterable listSkillsets() { @ServiceMethod(returns = ReturnType.COLLECTION) public PagedIterable listSkillsets(Context context) { try { - return new PagedIterable<>( - () -> MappingUtils.mapPagedSkillsets(listSkillsetsWithResponse(null, context))); + return new PagedIterable<>(() -> MappingUtils.mapPagedSkillsets(listSkillsetsWithResponse(null, context))); } catch (RuntimeException ex) { throw LOGGER.logExceptionAsError(ex); } @@ -1827,12 +1826,11 @@ public void resetDocuments(String indexerName, Boolean overwrite, List d @ServiceMethod(returns = ReturnType.SINGLE) public Response resetDocumentsWithResponse(SearchIndexer indexer, Boolean overwrite, List documentKeys, List datasourceDocumentIds, Context context) { - DocumentKeysOrIds documentKeysOrIds = new DocumentKeysOrIds() - .setDocumentKeys(documentKeys) - .setDatasourceDocumentIds(datasourceDocumentIds); + DocumentKeysOrIds documentKeysOrIds + = new DocumentKeysOrIds().setDocumentKeys(documentKeys).setDatasourceDocumentIds(datasourceDocumentIds); - return Utility.executeRestCallWithExceptionHandling(() -> restClient.getIndexers().resetDocsWithResponse( - indexer.getName(), overwrite, documentKeysOrIds, null, context), LOGGER); + return Utility.executeRestCallWithExceptionHandling(() -> restClient.getIndexers() + .resetDocsWithResponse(indexer.getName(), overwrite, documentKeysOrIds, null, context), LOGGER); } /** @@ -1876,8 +1874,9 @@ public void resetSkills(String skillsetName, List skillNames) { @ServiceMethod(returns = ReturnType.SINGLE) public Response resetSkillsWithResponse(SearchIndexerSkillset skillset, List skillNames, Context context) { - return Utility.executeRestCallWithExceptionHandling(() -> restClient.getSkillsets() - .resetSkillsWithResponse(skillset.getName(), new SkillNames().setSkillNames(skillNames), null, - context), LOGGER); + return Utility.executeRestCallWithExceptionHandling( + () -> restClient.getSkillsets() + .resetSkillsWithResponse(skillset.getName(), new SkillNames().setSkillNames(skillNames), null, context), + LOGGER); } } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java index 2567800a93f2..5c4f092ca2db 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateDataSourceConnectionOptions.java @@ -24,8 +24,8 @@ public final class CreateOrUpdateDataSourceConnectionOptions { * @throws NullPointerException If {@code dataSourceConnection} is null. */ public CreateOrUpdateDataSourceConnectionOptions(SearchIndexerDataSourceConnection dataSourceConnection) { - this.dataSourceConnection = Objects.requireNonNull(dataSourceConnection, - "'dataSourceConnection' cannot be null."); + this.dataSourceConnection + = Objects.requireNonNull(dataSourceConnection, "'dataSourceConnection' cannot be null."); } /** @@ -70,7 +70,8 @@ public boolean isOnlyIfUnchanged() { * SearchIndexerDataSourceConnection data source connection} ignores cache reset requirements. * @return The updated CreateOrUpdateDataSourceConnectionOptions object. */ - public CreateOrUpdateDataSourceConnectionOptions setCacheResetRequirementsIgnored(Boolean cacheResetRequirementsIgnored) { + public CreateOrUpdateDataSourceConnectionOptions + setCacheResetRequirementsIgnored(Boolean cacheResetRequirementsIgnored) { this.cacheResetRequirementsIgnored = cacheResetRequirementsIgnored; return this; } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java index a37711d82146..f726fa0da869 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateIndexerOptions.java @@ -67,8 +67,8 @@ public boolean isOnlyIfUnchanged() { * {@link SearchIndexer indexer} disables cache reprocessing change detection. * @return The updated CreateOrUpdateIndexerOptions object. */ - public CreateOrUpdateIndexerOptions setCacheReprocessingChangeDetectionDisabled( - Boolean cacheReprocessingChangeDetectionDisabled) { + public CreateOrUpdateIndexerOptions + setCacheReprocessingChangeDetectionDisabled(Boolean cacheReprocessingChangeDetectionDisabled) { this.cacheReprocessingChangeDetectionDisabled = cacheReprocessingChangeDetectionDisabled; return this; } diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java index a6fc76ef5ee9..7fe6d7abd6b6 100644 --- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java +++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/models/CreateOrUpdateSkillsetOptions.java @@ -67,8 +67,8 @@ public boolean isOnlyIfUnchanged() { * {@link SearchIndexerSkillset skillset} disables cache reprocessing change detection. * @return The updated CreateOrUpdateSkillsetOptions object. */ - public CreateOrUpdateSkillsetOptions setCacheReprocessingChangeDetectionDisabled( - Boolean cacheReprocessingChangeDetectionDisabled) { + public CreateOrUpdateSkillsetOptions + setCacheReprocessingChangeDetectionDisabled(Boolean cacheReprocessingChangeDetectionDisabled) { this.cacheReprocessingChangeDetectionDisabled = cacheReprocessingChangeDetectionDisabled; return this; } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java index 9eb262e07f0d..e54759d8f849 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchAliasTests.java @@ -73,8 +73,7 @@ protected void afterTest() { return; // Running in PLAYBACK, no need to clean-up. } - SearchIndexClient cleanupClient = new SearchIndexClientBuilder() - .endpoint(SEARCH_ENDPOINT) + SearchIndexClient cleanupClient = new SearchIndexClientBuilder().endpoint(SEARCH_ENDPOINT) .credential(getTestTokenCredential()) .buildClient(); @@ -111,45 +110,43 @@ public void canCreateAliasAsync() { SearchAlias expectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), Collections.singletonList(HOTEL_INDEX_NAME1)); - StepVerifier.create(indexAsyncClient.createAlias(expectedAlias)) - .assertNext(searchAlias -> { - aliasesToDelete.add(searchAlias.getName()); - assertEquals(expectedAlias.getName(), searchAlias.getName()); - assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); - }) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.createAlias(expectedAlias)).assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + }).verifyComplete(); - StepVerifier.create(indexAsyncClient.getAlias(expectedAlias.getName())) - .assertNext(searchAlias -> { - assertEquals(expectedAlias.getName(), searchAlias.getName()); - assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); - }) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.getAlias(expectedAlias.getName())).assertNext(searchAlias -> { + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + }).verifyComplete(); } @Test public void cannotCreateAliasOnNonExistentIndexSync() { - assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias("my-alias", - Collections.singletonList("index-that-does-not-exist")))); + assertThrows(HttpResponseException.class, () -> indexClient + .createAlias(new SearchAlias("my-alias", Collections.singletonList("index-that-does-not-exist")))); } @Test public void cannotCreateAliasOnNonExistentIndexAsync() { - StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias("my-alias", - Collections.singletonList("index-that-does-not-exist")))) + StepVerifier + .create(indexAsyncClient + .createAlias(new SearchAlias("my-alias", Collections.singletonList("index-that-does-not-exist")))) .verifyError(HttpResponseException.class); } @Test public void cannotCreateAliasWithInvalidNameSync() { - assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias("--invalid--alias-name", - Collections.singletonList(HOTEL_INDEX_NAME1)))); + assertThrows(HttpResponseException.class, () -> indexClient + .createAlias(new SearchAlias("--invalid--alias-name", Collections.singletonList(HOTEL_INDEX_NAME1)))); } @Test public void cannotCreateAliasWithInvalidNameAsync() { - StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias("--invalid--alias-name", - Collections.singletonList(HOTEL_INDEX_NAME1)))) + StepVerifier + .create(indexAsyncClient + .createAlias(new SearchAlias("--invalid--alias-name", Collections.singletonList(HOTEL_INDEX_NAME1)))) .verifyError(HttpResponseException.class); } @@ -163,8 +160,8 @@ public void cannotCreateMultipleAliasesWithTheSameNameSync() { assertEquals(expectedAlias.getName(), searchAlias.getName()); assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); - assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias(expectedAlias.getName(), - Collections.singletonList(HOTEL_INDEX_NAME1)))); + assertThrows(HttpResponseException.class, () -> indexClient + .createAlias(new SearchAlias(expectedAlias.getName(), Collections.singletonList(HOTEL_INDEX_NAME1)))); } @Test @@ -172,29 +169,29 @@ public void cannotCreateMultipleAliasesWithTheSameNameAsync() { SearchAlias expectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), Collections.singletonList(HOTEL_INDEX_NAME1)); - StepVerifier.create(indexAsyncClient.createAlias(expectedAlias)) - .assertNext(searchAlias -> { - aliasesToDelete.add(searchAlias.getName()); - assertEquals(expectedAlias.getName(), searchAlias.getName()); - assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); - }) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.createAlias(expectedAlias)).assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(expectedAlias.getName(), searchAlias.getName()); + assertEquals(expectedAlias.getIndexes(), searchAlias.getIndexes()); + }).verifyComplete(); - StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias(expectedAlias.getName(), - Collections.singletonList(HOTEL_INDEX_NAME1)))) + StepVerifier + .create(indexAsyncClient + .createAlias(new SearchAlias(expectedAlias.getName(), Collections.singletonList(HOTEL_INDEX_NAME1)))) .verifyError(HttpResponseException.class); } @Test public void cannotCreateAliasWithMultipleIndexesSync() { - assertThrows(HttpResponseException.class, () -> indexClient.createAlias(new SearchAlias("my-alias", - Arrays.asList(HOTEL_INDEX_NAME1, HOTEL_INDEX_NAME2)))); + assertThrows(HttpResponseException.class, () -> indexClient + .createAlias(new SearchAlias("my-alias", Arrays.asList(HOTEL_INDEX_NAME1, HOTEL_INDEX_NAME2)))); } @Test public void cannotCreateAliasWithMultipleIndexesAsync() { - StepVerifier.create(indexAsyncClient.createAlias(new SearchAlias("my-alias", - Arrays.asList(HOTEL_INDEX_NAME1, HOTEL_INDEX_NAME2)))) + StepVerifier + .create(indexAsyncClient + .createAlias(new SearchAlias("my-alias", Arrays.asList(HOTEL_INDEX_NAME1, HOTEL_INDEX_NAME2)))) .verifyError(HttpResponseException.class); } @@ -222,24 +219,20 @@ public void canCreateMultipleAliasesReferencingTheSameIndexAsync() { SearchAlias firstExpectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), Collections.singletonList(HOTEL_INDEX_NAME1)); - StepVerifier.create(indexAsyncClient.createAlias(firstExpectedAlias)) - .assertNext(searchAlias -> { - aliasesToDelete.add(searchAlias.getName()); - assertEquals(firstExpectedAlias.getName(), searchAlias.getName()); - assertEquals(firstExpectedAlias.getIndexes(), searchAlias.getIndexes()); - }) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.createAlias(firstExpectedAlias)).assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(firstExpectedAlias.getName(), searchAlias.getName()); + assertEquals(firstExpectedAlias.getIndexes(), searchAlias.getIndexes()); + }).verifyComplete(); SearchAlias secondExpectedAlias = new SearchAlias(testResourceNamer.randomName("my-alias", 32), Collections.singletonList(HOTEL_INDEX_NAME1)); - StepVerifier.create(indexAsyncClient.createAlias(secondExpectedAlias)) - .assertNext(searchAlias -> { - aliasesToDelete.add(searchAlias.getName()); - assertEquals(secondExpectedAlias.getName(), searchAlias.getName()); - assertEquals(secondExpectedAlias.getIndexes(), searchAlias.getIndexes()); - }) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.createAlias(secondExpectedAlias)).assertNext(searchAlias -> { + aliasesToDelete.add(searchAlias.getName()); + assertEquals(secondExpectedAlias.getName(), searchAlias.getName()); + assertEquals(secondExpectedAlias.getIndexes(), searchAlias.getIndexes()); + }).verifyComplete(); } @Test @@ -258,18 +251,15 @@ public void canUpdateAliasAfterCreationSync() { @Test public void canUpdateAliasAfterCreationAsync() { String aliasName = testResourceNamer.randomName("my-alias", 32); - indexAsyncClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))) - .block(); + indexAsyncClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))).block(); aliasesToDelete.add(aliasName); SearchAlias expectedUpdatedAlias = new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME2)); - StepVerifier.create(indexAsyncClient.createOrUpdateAlias(expectedUpdatedAlias)) - .assertNext(updatedAlias -> { - assertEquals(expectedUpdatedAlias.getName(), updatedAlias.getName()); - assertEquals(expectedUpdatedAlias.getIndexes(), updatedAlias.getIndexes()); - }) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.createOrUpdateAlias(expectedUpdatedAlias)).assertNext(updatedAlias -> { + assertEquals(expectedUpdatedAlias.getName(), updatedAlias.getName()); + assertEquals(expectedUpdatedAlias.getIndexes(), updatedAlias.getIndexes()); + }).verifyComplete(); } @Test @@ -288,8 +278,7 @@ public void canDeleteAliasSync() { @Test public void canDeleteAliasAsync() { String aliasName = testResourceNamer.randomName("my-alias", 32); - indexAsyncClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))) - .block(); + indexAsyncClient.createAlias(new SearchAlias(aliasName, Collections.singletonList(HOTEL_INDEX_NAME1))).block(); StepVerifier.create(indexAsyncClient.deleteAlias(aliasName)).verifyComplete(); @@ -311,29 +300,23 @@ public void cannotDeleteIndexWithAliasSyncAndAsync() { assertThrows(HttpResponseException.class, () -> indexClient.deleteIndex(HOTEL_INDEX_NAME1)); assertDoesNotThrow(() -> indexClient.getIndex(HOTEL_INDEX_NAME1)); - StepVerifier.create(indexAsyncClient.deleteIndex(HOTEL_INDEX_NAME1)) - .verifyError(HttpResponseException.class); + StepVerifier.create(indexAsyncClient.deleteIndex(HOTEL_INDEX_NAME1)).verifyError(HttpResponseException.class); - StepVerifier.create(indexAsyncClient.getIndex(HOTEL_INDEX_NAME1)) - .expectNextCount(1) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.getIndex(HOTEL_INDEX_NAME1)).expectNextCount(1).verifyComplete(); } @Test public void canListAliasesSyncAndAsync() { String firstAliasName = testResourceNamer.randomName("my-alias", 32); - indexClient.createAlias(new SearchAlias(firstAliasName, - Collections.singletonList(HOTEL_INDEX_NAME1))); + indexClient.createAlias(new SearchAlias(firstAliasName, Collections.singletonList(HOTEL_INDEX_NAME1))); aliasesToDelete.add(firstAliasName); String secondAliasName = testResourceNamer.randomName("my-alias", 32); - indexClient.createAlias(new SearchAlias(secondAliasName, - Collections.singletonList(HOTEL_INDEX_NAME1))); + indexClient.createAlias(new SearchAlias(secondAliasName, Collections.singletonList(HOTEL_INDEX_NAME1))); aliasesToDelete.add(secondAliasName); String thirdAliasName = testResourceNamer.randomName("my-alias", 32); - indexClient.createAlias(new SearchAlias(thirdAliasName, - Collections.singletonList(HOTEL_INDEX_NAME1))); + indexClient.createAlias(new SearchAlias(thirdAliasName, Collections.singletonList(HOTEL_INDEX_NAME1))); aliasesToDelete.add(thirdAliasName); List syncAliases = indexClient.listAliases().stream().collect(Collectors.toList()); @@ -342,24 +325,25 @@ public void canListAliasesSyncAndAsync() { assertTrue(syncAliases.stream().anyMatch(alias -> alias.getName().equals(secondAliasName))); assertTrue(syncAliases.stream().anyMatch(alias -> alias.getName().equals(thirdAliasName))); - StepVerifier.create(indexAsyncClient.listAliases().collectList()) - .assertNext(asyncAliases -> { - assertEquals(3, asyncAliases.size()); - assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(firstAliasName))); - assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(secondAliasName))); - assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(thirdAliasName))); - }) - .verifyComplete(); + StepVerifier.create(indexAsyncClient.listAliases().collectList()).assertNext(asyncAliases -> { + assertEquals(3, asyncAliases.size()); + assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(firstAliasName))); + assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(secondAliasName))); + assertTrue(asyncAliases.stream().anyMatch(alias -> alias.getName().equals(thirdAliasName))); + }).verifyComplete(); } @Test public void canInspectAliasUsageInServiceStatisticsSyncAndAsync() { - aliasesToDelete.add(indexClient.createAlias(new SearchAlias(testResourceNamer.randomName("my-alias", 32), - Collections.singletonList(HOTEL_INDEX_NAME1))).getName()); - aliasesToDelete.add(indexClient.createAlias(new SearchAlias(testResourceNamer.randomName("my-alias", 32), - Collections.singletonList(HOTEL_INDEX_NAME1))).getName()); - aliasesToDelete.add(indexClient.createAlias(new SearchAlias(testResourceNamer.randomName("my-alias", 32), - Collections.singletonList(HOTEL_INDEX_NAME1))).getName()); + aliasesToDelete.add(indexClient.createAlias( + new SearchAlias(testResourceNamer.randomName("my-alias", 32), Collections.singletonList(HOTEL_INDEX_NAME1))) + .getName()); + aliasesToDelete.add(indexClient.createAlias( + new SearchAlias(testResourceNamer.randomName("my-alias", 32), Collections.singletonList(HOTEL_INDEX_NAME1))) + .getName()); + aliasesToDelete.add(indexClient.createAlias( + new SearchAlias(testResourceNamer.randomName("my-alias", 32), Collections.singletonList(HOTEL_INDEX_NAME1))) + .getName()); // Give 3 seconds for alias creation to propagate. sleepIfRunningAgainstService(3000); @@ -367,8 +351,8 @@ public void canInspectAliasUsageInServiceStatisticsSyncAndAsync() { assertEquals(3, indexClient.getServiceStatistics().getCounters().getAliasCounter().getUsage()); StepVerifier.create(indexAsyncClient.getServiceStatistics()) - .assertNext(serviceStatistics -> assertEquals(3, - serviceStatistics.getCounters().getAliasCounter().getUsage())) + .assertNext( + serviceStatistics -> assertEquals(3, serviceStatistics.getCounters().getAliasCounter().getUsage())) .verifyComplete(); } } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java index d3c7fb993bde..ef53897b0589 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/VectorSearchTests.java @@ -412,15 +412,15 @@ public void testVectorSearchCompressionsEnableRescoringDiscardOriginalsAsync() { indexesToDelete.add(indexName); - SearchIndex retrievedIndex = searchIndexClient.getIndex(indexName).block(); - assert retrievedIndex != null; - assertEquals(1, retrievedIndex.getVectorSearch().getCompressions().size()); - BinaryQuantizationCompression compression - = (BinaryQuantizationCompression) retrievedIndex.getVectorSearch().getCompressions().get(0); - assertEquals(compressionName, compression.getCompressionName()); - assertEquals(true, compression.getRescoringOptions().isEnableRescoring()); - assertEquals(VectorSearchCompressionRescoreStorageMethod.DISCARD_ORIGINALS, - compression.getRescoringOptions().getRescoreStorageMethod()); + StepVerifier.create(searchIndexClient.getIndex(indexName)).assertNext(retrievedIndex -> { + assertEquals(1, retrievedIndex.getVectorSearch().getCompressions().size()); + BinaryQuantizationCompression compression + = (BinaryQuantizationCompression) retrievedIndex.getVectorSearch().getCompressions().get(0); + assertEquals(compressionName, compression.getCompressionName()); + assertEquals(true, compression.getRescoringOptions().isEnableRescoring()); + assertEquals(VectorSearchCompressionRescoreStorageMethod.DISCARD_ORIGINALS, + compression.getRescoringOptions().getRescoreStorageMethod()); + }).verifyComplete(); } private static void compareFloatListToDeserializedFloatList(List actual) { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderServiceTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderServiceTests.java index af83ccb9b5bf..716216098a95 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderServiceTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderServiceTests.java @@ -37,7 +37,6 @@ protected void beforeTest() { @Override protected void afterTest() { super.afterTest(); - assert client != null; for (String index : indexesToDelete) { client.deleteIndex(index); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java index cf7534b5bd45..447e79cb0718 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java @@ -354,8 +354,8 @@ public static final class ValidNormalizer { @ParameterizedTest @ValueSource(classes = { NonStringNormalizer.class, MissingFunctionalityNormalizer.class }) public void invalidNormalizerField(Class type) { - RuntimeException ex = assertThrows(RuntimeException.class, - () -> SearchIndexClient.buildSearchFields(type, null)); + RuntimeException ex + = assertThrows(RuntimeException.class, () -> SearchIndexClient.buildSearchFields(type, null)); assertTrue(ex.getMessage().contains("A field with a normalizer name")); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java index 4aa96e07b705..c70d6978ebff 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/IndexManagementTests.java @@ -3,8 +3,6 @@ package com.azure.search.documents.indexes; import com.azure.core.exception.HttpResponseException; -import com.azure.core.http.rest.PagedFlux; -import com.azure.core.http.rest.PagedIterable; import com.azure.core.http.rest.Response; import com.azure.core.test.TestMode; import com.azure.core.util.Context; @@ -27,7 +25,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; - import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; import reactor.core.publisher.Mono; @@ -55,6 +52,7 @@ import static com.azure.search.documents.TestHelpers.verifyHttpResponseError; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -838,19 +836,16 @@ public void canCreateAndGetIndexStatsAsync() { @Test public void canCreateAndGetIndexStatsSummarySync() { - List indexNames = new ArrayList<>(); - PagedIterable statsSummary = client.getIndexStatsSummary(); - assert (!statsSummary.stream().findAny().isPresent()); + assertFalse(client.getIndexStatsSummary().stream().findAny().isPresent(), "Unexpected index stats summary."); SearchIndex index = createTestIndex(null); indexNames.add(index.getName()); client.createOrUpdateIndex(index); indexesToDelete.add(index.getName()); - statsSummary = client.getIndexStatsSummary(); - assert (statsSummary.stream().count() == 1); + assertEquals(1, client.getIndexStatsSummary().stream().count()); for (int i = 0; i < 4; i++) { index = createTestIndex(null); @@ -859,12 +854,14 @@ public void canCreateAndGetIndexStatsSummarySync() { indexesToDelete.add(index.getName()); } - statsSummary = client.getIndexStatsSummary(); - assertEquals(5, statsSummary.stream().count()); List returnedNames - = statsSummary.stream().map(IndexStatisticsSummary::getName).collect(Collectors.toList()); + = client.getIndexStatsSummary().stream().map(IndexStatisticsSummary::getName).collect(Collectors.toList()); + assertEquals(5, returnedNames.size()); + for (String name : indexNames) { - assert (returnedNames.contains(name)); + assertTrue(returnedNames.contains(name), + () -> String.format("Stats summary didn't contain expected index '%s'. Found: '%s'", name, + String.join(", ", returnedNames))); } } @@ -890,20 +887,17 @@ public void canCreateAndGetIndexStatsSummaryAsync() { indexesToDelete.add(index.getName()); } - List returnedNames = new ArrayList<>(); - PagedFlux statsSummary = asyncClient.getIndexStatsSummary(); + StepVerifier.create(asyncClient.getIndexStatsSummary().map(IndexStatisticsSummary::getName).collectList()) + .assertNext(returnedNames -> { + assertEquals(5, returnedNames.size()); - StepVerifier.create(statsSummary) - .consumeNextWith(indexStatsSummary -> returnedNames.add(indexStatsSummary.getName())) - .consumeNextWith(indexStatsSummary -> returnedNames.add(indexStatsSummary.getName())) - .consumeNextWith(indexStatsSummary -> returnedNames.add(indexStatsSummary.getName())) - .consumeNextWith(indexStatsSummary -> returnedNames.add(indexStatsSummary.getName())) - .consumeNextWith(indexStatsSummary -> returnedNames.add(indexStatsSummary.getName())) + for (String name : indexNames) { + assertTrue(returnedNames.contains(name), + () -> String.format("Stats summary didn't contain expected index '%s'. Found: '%s'", name, + String.join(", ", returnedNames))); + } + }) .verifyComplete(); - - for (String name : indexNames) { - assert (returnedNames.contains(name)); - } } static SearchIndex mutateCorsOptionsInIndex(SearchIndex index) { diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java index 020b44eda983..3b895f74c147 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/OptionBagsTests.java @@ -44,20 +44,18 @@ public void nullRequiredValuesThrowNullPointerExceptions(Executable constructorC static Stream nullRequiredValuesThrowNullPointerExceptionsSupplier() { return Stream.of( - () -> new CreateOrUpdateDataSourceConnectionOptions((SearchIndexerDataSourceConnection) - FOOL_SPOTBUGS.get("value")), + () -> new CreateOrUpdateDataSourceConnectionOptions( + (SearchIndexerDataSourceConnection) FOOL_SPOTBUGS.get("value")), () -> new CreateOrUpdateIndexerOptions((SearchIndexer) FOOL_SPOTBUGS.get("value")), - () -> new CreateOrUpdateSkillsetOptions((SearchIndexerSkillset) FOOL_SPOTBUGS.get("value")) - ); + () -> new CreateOrUpdateSkillsetOptions((SearchIndexerSkillset) FOOL_SPOTBUGS.get("value"))); } @ParameterizedTest @MethodSource("getIndexingParametersConfigurationSupplier") public void getIndexingParametersConfiguration(Map configuration, Function parameterGetter, Object expected) { - IndexingParametersConfiguration indexingParametersConfiguration = new IndexingParameters() - .setConfiguration(configuration) - .getIndexingParametersConfiguration(); + IndexingParametersConfiguration indexingParametersConfiguration + = new IndexingParameters().setConfiguration(configuration).getIndexingParametersConfiguration(); assertEquals(expected, parameterGetter.apply(indexingParametersConfiguration)); } @@ -107,8 +105,7 @@ static Stream getIndexingParametersConfigurationSupplier() { createArguments("executionEnvironment", IndexerExecutionEnvironment.STANDARD, IndexingParametersConfiguration::getExecutionEnvironment), - createArguments("queryTimeout", "1:00:00", IndexingParametersConfiguration::getQueryTimeout) - ); + createArguments("queryTimeout", "1:00:00", IndexingParametersConfiguration::getQueryTimeout)); } static Arguments createArguments(String key, Object expected, diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexClientBuilderTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexClientBuilderTests.java index fb9f5791c329..83f4f1904f13 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexClientBuilderTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexClientBuilderTests.java @@ -37,6 +37,7 @@ import java.util.Collections; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -159,7 +160,7 @@ public Mono send(HttpRequest request) { return Mono.error(new IOException("IOException!")); } - assert !firstDate.equals(convertToDateObject(request.getHeaders().getValue(HttpHeaderName.DATE))); + assertNotEquals(firstDate, convertToDateObject(request.getHeaders().getValue(HttpHeaderName.DATE))); return Mono.just(new MockHttpResponse(request, 200)); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexerClientBuilderTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexerClientBuilderTests.java index e09164f4d075..bd3d273bd8fb 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexerClientBuilderTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/SearchIndexerClientBuilderTests.java @@ -37,6 +37,7 @@ import java.util.Collections; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -159,7 +160,7 @@ public Mono send(HttpRequest request) { return Mono.error(new IOException("IOException!")); } - assert !firstDate.equals(convertToDateObject(request.getHeaders().getValue(HttpHeaderName.DATE))); + assertNotEquals(firstDate, convertToDateObject(request.getHeaders().getValue(HttpHeaderName.DATE))); return Mono.just(new MockHttpResponse(request, 200)); } diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java index ee766cf1b769..adeef2ed0b68 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/models/SearchRequestUrlRewriterPolicyTests.java @@ -174,8 +174,9 @@ public static Stream correctUrlRewriteSupplier() { Arguments.of(toCallable(() -> searchIndexClient.createAliasWithResponse(alias, Context.NONE)), "https://test.search.windows.net/aliases"), - Arguments.of(toCallable(() -> searchIndexClient.createOrUpdateAliasWithResponse(alias, false, - Context.NONE)), aliasUrl), + Arguments.of( + toCallable(() -> searchIndexClient.createOrUpdateAliasWithResponse(alias, false, Context.NONE)), + aliasUrl), Arguments.of(toCallable(() -> searchIndexClient.getAliasWithResponse("alias", Context.NONE)), aliasUrl), Arguments.of(toCallable(() -> searchIndexClient.deleteAliasWithResponse(alias, true, Context.NONE)), aliasUrl), @@ -209,8 +210,9 @@ public static Stream correctUrlRewriteSupplier() { "https://test.search.windows.net/servicestats"), Arguments.of(toCallable(() -> searchIndexClient.createAliasWithResponse(alias, Context.NONE)), "https://test.search.windows.net/aliases"), - Arguments.of(toCallable(() -> searchIndexClient.createOrUpdateAliasWithResponse(alias, false, - Context.NONE)), aliasUrl), + Arguments.of( + toCallable(() -> searchIndexClient.createOrUpdateAliasWithResponse(alias, false, Context.NONE)), + aliasUrl), Arguments.of(toCallable(() -> searchIndexClient.getAliasWithResponse("alias", Context.NONE)), aliasUrl), Arguments.of(toCallable(() -> searchIndexClient.deleteAliasWithResponse(alias, true, Context.NONE)), aliasUrl), @@ -268,8 +270,9 @@ public static Stream correctUrlRewriteSupplier() { skillsetUrl), Arguments.of(toCallable(() -> searchIndexerClient.deleteSkillsetWithResponse(skillset, true, Context.NONE)), skillsetUrl), - Arguments.of(toCallable(() -> searchIndexerClient.resetSkillsWithResponse(skillset, emptyList(), - Context.NONE)), skillsetUrl + "/search.resetskills"), + Arguments.of( + toCallable(() -> searchIndexerClient.resetSkillsWithResponse(skillset, emptyList(), Context.NONE)), + skillsetUrl + "/search.resetskills"), Arguments.of( toCallable(searchIndexerAsyncClient.createOrUpdateDataSourceConnectionWithResponse(dataSource, true)), @@ -300,8 +303,10 @@ public static Stream correctUrlRewriteSupplier() { indexerUrl + "/search.run"), Arguments.of(toCallable(searchIndexerAsyncClient.getIndexerStatusWithResponse("indexer")), indexerUrl + "/search.status"), - Arguments.of(toCallable(searchIndexerAsyncClient.resetDocumentsWithResponse(indexer, null, emptyList(), - emptyList())), indexerUrl + "/search.resetdocs"), + Arguments.of( + toCallable( + searchIndexerAsyncClient.resetDocumentsWithResponse(indexer, null, emptyList(), emptyList())), + indexerUrl + "/search.resetdocs"), Arguments.of(toCallable(searchIndexerAsyncClient.createSkillsetWithResponse(skillset)), "https://test.search.windows.net/skillsets"), Arguments.of(toCallable(searchIndexerAsyncClient.getSkillsetWithResponse("skillset")), skillsetUrl), From a4a0673d43057e884390898fa04459dbcc63df23 Mon Sep 17 00:00:00 2001 From: alzimmermsft <48699787+alzimmermsft@users.noreply.github.com> Date: Tue, 2 Sep 2025 12:37:14 -0400 Subject: [PATCH 12/12] Finalize tests --- .../search/documents/KnowledgeAgentTests.java | 56 +++++++++++-------- .../search/documents/SearchTestBase.java | 4 +- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java index 8cc80d90c1c3..cda9f76faef4 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/KnowledgeAgentTests.java @@ -157,12 +157,14 @@ public void createKnowledgeAgentSync() { assertEquals(1, created.getModels().size()); KnowledgeAgentAzureOpenAIModel createdModel = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, created.getModels().get(0)); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), - createdModel.getAzureOpenAIParameters().getDeploymentName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), - createdModel.getAzureOpenAIParameters().getModelName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), - createdModel.getAzureOpenAIParameters().getResourceUrl()); + if (interceptorManager.isLiveMode()) { + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + createdModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + createdModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + createdModel.getAzureOpenAIParameters().getResourceUrl()); + } assertEquals(1, created.getKnowledgeSources().size()); assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, created.getKnowledgeSources().get(0).getName()); @@ -181,12 +183,14 @@ public void createKnowledgeAgentAsync() { assertEquals(1, created.getModels().size()); KnowledgeAgentAzureOpenAIModel createdModel = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, created.getModels().get(0)); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), - createdModel.getAzureOpenAIParameters().getDeploymentName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), - createdModel.getAzureOpenAIParameters().getModelName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), - createdModel.getAzureOpenAIParameters().getResourceUrl()); + if (interceptorManager.isLiveMode()) { + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + createdModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + createdModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + createdModel.getAzureOpenAIParameters().getResourceUrl()); + } assertEquals(1, created.getKnowledgeSources().size()); assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, created.getKnowledgeSources().get(0).getName()); @@ -207,12 +211,14 @@ public void getKnowledgeAgentSync() { assertEquals(1, retrieved.getModels().size()); KnowledgeAgentAzureOpenAIModel retrievedModel = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, retrieved.getModels().get(0)); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), - retrievedModel.getAzureOpenAIParameters().getDeploymentName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), - retrievedModel.getAzureOpenAIParameters().getModelName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), - retrievedModel.getAzureOpenAIParameters().getResourceUrl()); + if (interceptorManager.isLiveMode()) { + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + retrievedModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + retrievedModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + retrievedModel.getAzureOpenAIParameters().getResourceUrl()); + } assertEquals(1, retrieved.getKnowledgeSources().size()); assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, retrieved.getKnowledgeSources().get(0).getName()); @@ -234,12 +240,14 @@ public void getKnowledgeAgentAsync() { assertEquals(1, retrieved.getModels().size()); KnowledgeAgentAzureOpenAIModel retrievedModel = assertInstanceOf(KnowledgeAgentAzureOpenAIModel.class, retrieved.getModels().get(0)); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), - retrievedModel.getAzureOpenAIParameters().getDeploymentName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), - retrievedModel.getAzureOpenAIParameters().getModelName()); - assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), - retrievedModel.getAzureOpenAIParameters().getResourceUrl()); + if (interceptorManager.isLiveMode()) { + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getDeploymentName(), + retrievedModel.getAzureOpenAIParameters().getDeploymentName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getModelName(), + retrievedModel.getAzureOpenAIParameters().getModelName()); + assertEquals(OPEN_AI_AGENT_MODEL.getAzureOpenAIParameters().getResourceUrl(), + retrievedModel.getAzureOpenAIParameters().getResourceUrl()); + } assertEquals(1, retrieved.getKnowledgeSources().size()); assertEquals(HOTEL_KNOWLEDGE_SOURCE_NAME, retrieved.getKnowledgeSources().get(0).getName()); diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java index 38d29762c0a9..8b5a7c951c68 100644 --- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java +++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/SearchTestBase.java @@ -91,9 +91,9 @@ public abstract class SearchTestBase extends TestProxyTestBase { } protected static final String OPENAI_DEPLOYMENT_NAME - = Configuration.getGlobalConfiguration().get("SEARCH_OPENAI_DEPLOYMENT_NAME", "deployment-name"); + = Configuration.getGlobalConfiguration().get("SEARCH_OPENAI_DEPLOYMENT_NAME", "search-knowledge-agent-model"); protected static final String OPENAI_MODEL_NAME - = Configuration.getGlobalConfiguration().get("SEARCH_OPENAI_MODEL_NAME", "model-name"); + = Configuration.getGlobalConfiguration().get("SEARCH_OPENAI_MODEL_NAME", "gpt-4.1-nano"); protected static final String STORAGE_ACCOUNT_NAME = Configuration.getGlobalConfiguration().get("SEARCH_STORAGE_ACCOUNT_NAME", "storageaccount");