/** * Return all searchable properties of the given description. Complex properties * {@link TypeName#PODO} and {@link TypeName#COLLECTION} are not returned, but their inner * primitive type leaf properties up to a configurable level are. They are returned in * {@link QuerySpecification} format. * * @see {@link QuerySpecification#buildCompositeFieldName(String...)} */ public static Set<String> getExpandedQueryPropertyNames(ServiceDocumentDescription description) { if (description == null) { throw new IllegalArgumentException("description is required"); } return getExpandedQueryPropertyNames(description.propertyDescriptions, MAX_NEST_LEVEL_EXPAND_PROPERTY); }
/** * Merges a list of @ServiceDocumentQueryResult that were already <b>sorted</b> on <i>documentLink</i>. * The merge will be done in linear time. * * @param dataSources A list of @ServiceDocumentQueryResult <b>sorted</b> on <i>documentLink</i>. * @param isAscOrder Whether the document links are sorted in ascending order. * @return The merging result. */ public static void mergeQueryResults( List<ServiceDocumentQueryResult> dataSources, boolean isAscOrder, ServiceDocumentQueryResult result) { mergeQueryResults(dataSources, isAscOrder, EnumSet.noneOf(QueryOption.class), result); }
mergeCountQueries(dataSources, result); return;
/** * Process the query task results for a broadcast query or a query with read * after write semantics (which uses a broadcast query under the covers) * @param host The service host on which the query was invoked * @param dataSources A list of @ServiceDocumentQueryResult <b>sorted</b> on <i>documentLink</i>. * @param isAscOrder Whether the document links are sorted in ascending order. * @param queryOptions Query options on the original query * @param nodeGroupResponse Node group response obtained as part of the broadcast query * @param result Result object to populate * @param onCompletion Consumer to invoke once processing is complete */ public static void processQueryResults(ServiceHost host, List<ServiceDocumentQueryResult> dataSources, boolean isAscOrder, EnumSet<QueryOption> queryOptions, NodeGroupBroadcastResponse nodeGroupResponse, ServiceDocumentQueryResult result, BiConsumer<ServiceDocumentQueryResult, Throwable> onCompletion) { if (queryOptions != null && queryOptions.contains(QueryOption.READ_AFTER_WRITE_CONSISTENCY)) { mergeForReadAfterWriteConsistency(host, dataSources, isAscOrder, queryOptions, nodeGroupResponse, result, onCompletion); } else { mergeQueryResults(dataSources, isAscOrder, queryOptions, result); onCompletion.accept(result, null); } } /**
QueryTaskUtils.failTask(get, e); return; task.querySpec.context = null; task.taskInfo.stage = TaskStage.FINISHED; QueryTaskUtils.expandLinks(getHost(), task, get); QueryTaskUtils.failTask(get, ex); return;
scheduleTaskExpiration(task); }); QueryTaskUtils.expandLinks(getHost(), task, directOp); } else { if (!task.querySpec.options.contains(QueryOption.EXPAND_LINKS)) { Operation dummyOp = Operation.createGet(getHost().getUri()).setCompletion(c) .setReferer(getUri()); QueryTaskUtils.expandLinks(getHost(), task, dummyOp);
QueryTaskUtils.processQueryResults(getHost(), queryResults, isAscOrder, this.spec.options, this.nodeGroupResponse, mergeResults, onCompletion);
}); if (getOps.size() == 0) { onCompletion.accept(populateResultObject(documents, queryOptions, returnResult, isAscOrder), null); return; documents.put(jsonObject.documentSelfLink, rawObject); onCompletion.accept(populateResultObject(documents, queryOptions, returnResult, isAscOrder), null); }).sendWith(host);
QueryTaskUtils.failTask(get, e); return; task.querySpec.context = null; task.taskInfo.stage = TaskStage.FINISHED; QueryTaskUtils.expandLinks(getHost(), task, get); QueryTaskUtils.failTask(get, ex);
ServiceDocumentQueryResult result = new ServiceDocumentQueryResult(); result.queryTimeMicros = queryTask.taskInfo.durationMicros; QueryTaskUtils.processQueryResults(getHost(), queryResults, isAscOrder, queryTask.querySpec.options, nodeGroupResponse, result, onCompletion); } else {
private static Set<String> getExpandedQueryPropertyNames( Map<String, PropertyDescription> propertyDescriptions, int complexFieldNestLevel) { Set<String> result = new HashSet<>(); for (Entry<String, PropertyDescription> entry : propertyDescriptions.entrySet()) { result.addAll(getExpandedQueryPropertyNames(entry.getKey(), entry.getValue(), complexFieldNestLevel)); } return result; }
@Test public void testMergeQueryResultsWhenCountOptions() { ServiceDocumentQueryResult result1 = createServiceDocumentQueryResult( new int[] { 9, 7, 5, 4, 3, 1 }); result1.documentLinks.clear(); result1.documents.clear(); ServiceDocumentQueryResult result2 = createServiceDocumentQueryResult( new int[] { 9, 6, 5, 4, 3, 2, 10 }); result2.documentLinks.clear(); result2.documents.clear(); ServiceDocumentQueryResult result3 = createServiceDocumentQueryResult( new int[] { 8, 4, 3, 2, 10, 1 }); result3.documentLinks.clear(); result3.documents.clear(); List<ServiceDocumentQueryResult> resultsToMerge = Arrays.asList(result1, result2, result3); ServiceDocumentQueryResult mergeResult = new ServiceDocumentQueryResult(); QueryTaskUtils.mergeQueryResults(resultsToMerge, false, EnumSet.of(QueryOption.COUNT), mergeResult); assertEquals(result2.documentCount, mergeResult.documentCount); }
Set<String> innerPropertyNames = getExpandedQueryPropertyNames( pd.fieldDescriptions, complexFieldNestLevel - 1); Set<String> innerPropertyNames = getExpandedQueryPropertyNames( QuerySpecification.COLLECTION_FIELD_SUFFIX, pd.elementDescription, complexFieldNestLevel - 1);
@Test public void testMergeQueryResultsWhenCountOptions() { ServiceDocumentQueryResult result1 = createServiceDocumentQueryResult( new int[] { 9, 7, 5, 4, 3, 1 }); result1.documentLinks.clear(); result1.documents.clear(); ServiceDocumentQueryResult result2 = createServiceDocumentQueryResult( new int[] { 9, 6, 5, 4, 3, 2, 10 }); result2.documentLinks.clear(); result2.documents.clear(); ServiceDocumentQueryResult result3 = createServiceDocumentQueryResult( new int[] { 8, 4, 3, 2, 10, 1 }); result3.documentLinks.clear(); result3.documents.clear(); List<ServiceDocumentQueryResult> resultsToMerge = Arrays.asList(result1, result2, result3); ServiceDocumentQueryResult mergeResult = new ServiceDocumentQueryResult(); QueryTaskUtils.mergeQueryResults(resultsToMerge, false, EnumSet.of(QueryOption.COUNT), mergeResult); assertEquals(result2.documentCount, mergeResult.documentCount); }
@Test public void testGetQueryPropertyNames() throws Throwable { ServiceDocumentDescription desc = Builder.create().buildDescription( ExampleServiceState.class); Set<String> queryPropertyNames = QueryTaskUtils.getExpandedQueryPropertyNames(desc); Set<String> expectedPropertyNames = new HashSet<>(); expectedPropertyNames.add(ExampleServiceState.FIELD_NAME_COUNTER); expectedPropertyNames.add(ExampleServiceState.FIELD_NAME_SORTED_COUNTER); expectedPropertyNames.add(ExampleServiceState.FIELD_NAME_NAME); expectedPropertyNames.add(ExampleServiceState.FIELD_NAME_ID); expectedPropertyNames.add(ExampleServiceState.FIELD_NAME_REQUIRED); expectedPropertyNames.add(ExampleServiceState.FIELD_NAME_KEY_VALUES); expectedPropertyNames.add(ExampleServiceState.FIELD_NAME_IS_FROM_MIGRATION); expectedPropertyNames.add("tags.item"); assertEquals(expectedPropertyNames, queryPropertyNames); }
@Test public void testMergeQueryResultsWithAllEmpty() { ServiceDocumentQueryResult result1 = createServiceDocumentQueryResult(new int[] {}); ServiceDocumentQueryResult result2 = createServiceDocumentQueryResult(new int[] {}); ServiceDocumentQueryResult result3 = createServiceDocumentQueryResult(new int[] {}); List<ServiceDocumentQueryResult> resultsToMerge = Arrays.asList(result1, result2, result3); ServiceDocumentQueryResult mergeResult = new ServiceDocumentQueryResult(); QueryTaskUtils.mergeQueryResults(resultsToMerge, true, mergeResult); assertTrue(verifyMergeResult(mergeResult, new int[] {})); }
@Test public void testGetMultiLevelNestedQueryPropertyNames() throws Throwable { ServiceDocumentDescription desc = Builder.create().buildDescription( ComplexServiceState.class); Set<String> queryPropertyNames = QueryTaskUtils.getExpandedQueryPropertyNames(desc); Set<String> expectedPropertyNames = new HashSet<>(); expectedPropertyNames.add("name"); expectedPropertyNames.add("innerServices.item.nameInner"); expectedPropertyNames.add("singleInnerService.nameInner"); expectedPropertyNames.add("singleInnerService.singleInnerService.nameSecondInner"); assertEquals(expectedPropertyNames, queryPropertyNames); }
@Test public void testMergeQueryResultsWithEmptySet() { ServiceDocumentQueryResult result1 = createServiceDocumentQueryResult( new int[] { 1, 3, 4, 5, 7, 8, 9 }); ServiceDocumentQueryResult result2 = createServiceDocumentQueryResult( new int[] { 10, 2, 3, 4, 5, 6, 9 }); ServiceDocumentQueryResult result3 = createServiceDocumentQueryResult(new int[] {}); List<ServiceDocumentQueryResult> resultsToMerge = Arrays.asList(result1, result2, result3); ServiceDocumentQueryResult mergeResult = new ServiceDocumentQueryResult(); QueryTaskUtils.mergeQueryResults(resultsToMerge, true, mergeResult); assertTrue(verifyMergeResult(mergeResult, new int[] { 1, 10, 2, 3, 4, 5, 6, 7, 8, 9 })); }
@Test public void testGetMultiLevelNestedQueryPropertyNames() throws Throwable { ServiceDocumentDescription desc = Builder.create().buildDescription( ComplexServiceState.class); Set<String> queryPropertyNames = QueryTaskUtils.getExpandedQueryPropertyNames(desc); Set<String> expectedPropertyNames = new HashSet<>(); expectedPropertyNames.add("name"); expectedPropertyNames.add("innerServices.item.nameInner"); expectedPropertyNames.add("singleInnerService.nameInner"); expectedPropertyNames.add("singleInnerService.singleInnerService.nameSecondInner"); assertEquals(expectedPropertyNames, queryPropertyNames); }
@Test public void testMergeQueryResultsWithDifferentData() { ServiceDocumentQueryResult result1 = createServiceDocumentQueryResult( new int[] { 1, 3, 4, 5, 7, 9 }); ServiceDocumentQueryResult result2 = createServiceDocumentQueryResult( new int[] { 10, 2, 3, 4, 5, 6, 9 }); ServiceDocumentQueryResult result3 = createServiceDocumentQueryResult( new int[] { 1, 10, 2, 3, 4, 8 }); List<ServiceDocumentQueryResult> resultsToMerge = Arrays.asList(result1, result2, result3); ServiceDocumentQueryResult mergeResult = new ServiceDocumentQueryResult(); QueryTaskUtils.mergeQueryResults(resultsToMerge, true, mergeResult); assertTrue(verifyMergeResult(mergeResult, new int[] { 1, 10, 2, 3, 4, 5, 6, 7, 8, 9 })); }