CreateDefinedIndexesFunction implements InternalFunction<Set<RegionConfig.Index>> { @Override @SuppressWarnings("deprecation") public void execute(FunctionContext<Set<RegionConfig.Index>> context) { Cache cache = context.getCache(); QueryService queryService = cache.getQueryService(); ResultSender<CliFunctionResult> sender = context.getResultSender(); String memberId = cache.getDistributedSystem().getDistributedMember().getId(); Set<RegionConfig.Index> indexDefinitions = context.getArguments(); try { for (RegionConfig.Index indexDefinition : indexDefinitions) { String indexName = indexDefinition.getName(); String regionPath = indexDefinition.getFromClause(); String indexedExpression = indexDefinition.getExpression(); org.apache.geode.cache.query.IndexType indexType = org.apache.geode.cache.query.IndexType.valueOfSynonym(indexDefinition.getType()); if (indexType == org.apache.geode.cache.query.IndexType.PRIMARY_KEY) { queryService.defineKeyIndex(indexName, indexedExpression, regionPath); } else if (indexType == org.apache.geode.cache.query.IndexType.HASH) { queryService.defineHashIndex(indexName, indexedExpression, regionPath); } else { queryService.defineIndex(indexName, indexedExpression, regionPath); } } List<Index> indexes = queryService.createDefinedIndexes(); if (!indexes.isEmpty()) { for (Index index : indexes) { sender.sendResult( new CliFunctionResult(memberId, true, "Created index " + index.getName())); } } else { sender.sendResult( new CliFunctionResult(memberId, true, CliStrings.DEFINE_INDEX__FAILURE__MSG)); } } catch (MultiIndexCreationException multiIndexCreationException) { List<String> failedIndexes = new ArrayList<>(multiIndexCreationException.getFailedIndexNames()); List<String> createdIndexes = indexDefinitions.stream().filter(i -> !failedIndexes.contains(i.getName())) .map(RegionConfig.Index::getName).collect(Collectors.toList()); for (String index : createdIndexes) { sender.sendResult(new CliFunctionResult(memberId, true, "Created index " + index)); } for (Map.Entry<String, Exception> ex : multiIndexCreationException.getExceptionsMap() .entrySet()) { sender.sendResult(new CliFunctionResult(memberId, false, String .format("Failed to create index %s: %s", ex.getKey(), ex.getValue().getMessage()))); } } catch (Exception ex) { sender.sendResult(new CliFunctionResult(memberId, false, ex.getMessage())); } finally { queryService.clearDefinedIndexes(); } sender.lastResult(null); }  @Override String getId(); @Override @SuppressWarnings("deprecation") void execute(FunctionContext<Set<RegionConfig.Index>> context);  }
@Test @SuppressWarnings("deprecation") public void noIndexDefinitionsAsFunctionArgument() throws Exception { context = createFunctionContext(Collections.emptySet()); function.execute(context); List<?> results = resultSender.getResults(); assertThat(results).isNotNull(); assertThat(results.size()).isEqualTo(2); Object firstResult = results.get(0); assertThat(firstResult).isInstanceOf(CliFunctionResult.class); assertThat(((CliFunctionResult) firstResult).isSuccessful()).isTrue(); assertThat(((CliFunctionResult) firstResult).getMessage()).isNotEmpty(); assertThat(((CliFunctionResult) firstResult).getMessage()).contains("No indexes defined"); }
@Test @SuppressWarnings("deprecation") public void noIndexPreviouslyDefinedInQueryService() throws Exception { when(queryService.createDefinedIndexes()).thenReturn(Collections.emptyList()); context = createFunctionContext(indexDefinitions); function.execute(context); List<?> results = resultSender.getResults(); assertThat(results).isNotNull(); assertThat(results.size()).isEqualTo(2); Object firstResult = results.get(0); assertThat(firstResult).isInstanceOf(CliFunctionResult.class); assertThat(((CliFunctionResult) firstResult).isSuccessful()).isTrue(); assertThat(((CliFunctionResult) firstResult).getMessage()).isNotEmpty(); assertThat(((CliFunctionResult) firstResult).getMessage()).contains("No indexes defined"); }
@Test public void multiIndexCreationExceptionThrowByQueryService() throws Exception { HashMap<String, Exception> exceptions = new HashMap<>(); exceptions.put("index1", new IndexCreationException("Mock Failure.")); exceptions.put("index3", new IndexCreationException("Another Mock Failure.")); when(queryService.createDefinedIndexes()) .thenThrow(new MultiIndexCreationException(exceptions)); context = createFunctionContext(indexDefinitions); function.execute(context); List<?> results = resultSender.getResults(); assertThat(results).isNotNull(); assertThat(results.size()).isEqualTo(4); CliFunctionResult result1 = (CliFunctionResult) results.get(0); assertThat(result1.isSuccessful()).isTrue(); assertThat(result1.getStatusMessage()).isEqualTo("Created index index2"); CliFunctionResult result2 = (CliFunctionResult) results.get(1); assertThat(result2.isSuccessful()).isFalse(); assertThat(result2.getStatusMessage()) .isEqualTo("Failed to create index index1: Mock Failure."); CliFunctionResult result3 = (CliFunctionResult) results.get(2); assertThat(result3.isSuccessful()).isFalse(); assertThat(result3.getStatusMessage()) .isEqualTo("Failed to create index index3: Another Mock Failure."); }
@Test public void unexpectedExceptionThrowByQueryService() throws Exception { when(queryService.createDefinedIndexes()).thenThrow(new RuntimeException("Mock Exception")); context = createFunctionContext(indexDefinitions); function.execute(context); List<?> results = resultSender.getResults(); assertThat(results).isNotNull(); assertThat(results.size()).isEqualTo(2); CliFunctionResult firstResult = (CliFunctionResult) results.get(0); assertThat(firstResult.isSuccessful()).isFalse(); assertThat(firstResult.getStatusMessage()).isEqualTo("Mock Exception"); }
@Test @SuppressWarnings("unchecked") public void creationSuccess() throws Exception { @SuppressWarnings("deprecation") Index index1 = mock(org.apache.geode.cache.query.internal.index.HashIndex.class); when(index1.getName()).thenReturn("index1"); when(index1.getRegion()).thenReturn(region1); Index index2 = mock(CompactMapRangeIndex.class); when(index2.getName()).thenReturn("index2"); when(index2.getRegion()).thenReturn(region2); Index index3 = mock(PrimaryKeyIndex.class); when(index3.getName()).thenReturn("index3"); when(index3.getRegion()).thenReturn(region1); when(queryService.createDefinedIndexes()).thenReturn(Arrays.asList(index1, index2, index3)); context = createFunctionContext(indexDefinitions); function.execute(context); List<?> results = resultSender.getResults(); assertThat(results).isNotNull(); assertThat(results.size()).isEqualTo(4); Object firstIndex = results.get(0); assertThat(firstIndex).isNotNull(); assertThat(firstIndex).isInstanceOf(CliFunctionResult.class); assertThat(((CliFunctionResult) firstIndex).isSuccessful()); }