You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by nn...@apache.org on 2017/09/28 06:11:20 UTC
[geode] branch develop updated: GEODE-3520: isValid API made public
This is an automated email from the ASF dual-hosted git repository.
nnag pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new acbd66c GEODE-3520: isValid API made public
acbd66c is described below
commit acbd66ce97b53506e927cc5ba881d7b2ba9b1b53
Author: nabarun <nn...@pivotal.io>
AuthorDate: Tue Aug 29 14:45:37 2017 -0700
GEODE-3520: isValid API made public
* In case an index update corrupts the index, the index will be marked invalid
* Queries will not use that index while executing queries.
* The API isValid had been made public so that users can find out if the index ia valid or not
* A new field has been added to the list index gfsh command which shows the isValid flag.
* If while loading the data index during its creation and it causes an exception, the index creation will fail.
---
.../java/org/apache/geode/cache/query/Index.java | 8 +
.../cache/query/internal/index/AbstractIndex.java | 3 +-
.../cache/query/internal/index/IndexManager.java | 27 +-
.../cache/query/internal/index/IndexProtocol.java | 2 -
.../geode/internal/cache/PartitionedRegion.java | 1 +
.../internal/cli/commands/ListIndexCommand.java | 1 +
.../internal/cli/domain/IndexDetails.java | 18 +-
.../apache/geode/cache/query/data/Portfolio.java | 4 +
.../query/dunit/CorruptedIndexIntegrationTest.java | 290 +++++++++++++++++++++
.../query/transaction/QueryAndJtaJUnitTest.java | 26 --
.../cli/commands/IndexCommandsDUnitTest.java | 18 ++
.../geode/codeAnalysis/sanctionedSerializables.txt | 4 +-
12 files changed, 365 insertions(+), 37 deletions(-)
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/Index.java b/geode-core/src/main/java/org/apache/geode/cache/query/Index.java
index b0ff47e..21867d0 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/Index.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/Index.java
@@ -80,6 +80,14 @@ public interface Index {
*/
public String getFromClause();
+
+ /**
+ * Get whether index is valid to be used in queries.
+ */
+ public default boolean isValid() {
+ return false;
+ }
+
/**
* Get the canonicalized fromClause for this index.
*/
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/AbstractIndex.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/AbstractIndex.java
index c0e7885..a59b049 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/AbstractIndex.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/AbstractIndex.java
@@ -484,6 +484,7 @@ public abstract class AbstractIndex implements IndexProtocol {
@Override
public boolean addIndexMapping(RegionEntry entry) throws IMQException {
addMapping(entry);
+
// if no exception, then success
return true;
}
@@ -516,7 +517,7 @@ public abstract class AbstractIndex implements IndexProtocol {
return true;
}
- @Override
+
public boolean isValid() {
return this.isValid;
}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java
index 2433178..12e7fd0 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java
@@ -1052,7 +1052,8 @@ public class IndexManager {
}
IndexProtocol index = (IndexProtocol) ind;
- if (((AbstractIndex) index).isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
+ if (index.isValid() && ((AbstractIndex) index).isPopulated()
+ && index.getType() != IndexType.PRIMARY_KEY) {
// Asif : If the current Index contains an entry inspite
// of add operation , this can only mean that Index
// has already acted on it during creation, so do not
@@ -1063,9 +1064,7 @@ public class IndexManager {
this.region.getFullPath(), entry.getKey());
}
start = ((AbstractIndex) index).updateIndexUpdateStats();
-
- index.addIndexMapping(entry);
-
+ addIndexMapping(entry, index);
((AbstractIndex) index).updateIndexUpdateStats(start);
}
}
@@ -1101,7 +1100,7 @@ public class IndexManager {
}
start = ((AbstractIndex) index).updateIndexUpdateStats();
- index.addIndexMapping(entry);
+ addIndexMapping(entry, index);
((AbstractIndex) index).updateIndexUpdateStats(start);
}
@@ -1156,6 +1155,24 @@ public class IndexManager {
}
}
+ private void addIndexMapping(RegionEntry entry, IndexProtocol index) throws IMQException {
+ try {
+ index.addIndexMapping(entry);
+ } catch (Exception exception) {
+ index.markValid(false);
+ setPRIndexAsInvalid((AbstractIndex) index);
+ logger.warn("Put operation for the entry corrupted the index : "
+ + ((AbstractIndex) index).indexName + " with the exception : \n " + exception);
+ }
+ }
+
+ private void setPRIndexAsInvalid(AbstractIndex index) {
+ if (index.prIndex != null) {
+ AbstractIndex prIndex = (AbstractIndex) index.prIndex;
+ prIndex.markValid(false);
+ }
+ }
+
private void waitBeforeUpdate() {
synchronized (indexes) {
++numCreators;
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexProtocol.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexProtocol.java
index ab07f15..a444387 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexProtocol.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexProtocol.java
@@ -157,8 +157,6 @@ public interface IndexProtocol extends Index {
throws TypeMismatchException, FunctionDomainException, NameResolutionException,
QueryInvocationTargetException;
- boolean isValid();
-
void markValid(boolean b);
void initializeIndex(boolean loadEntries) throws IMQException;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
index 907df88..0ada1f9 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
@@ -9626,6 +9626,7 @@ public class PartitionedRegion extends LocalRegion
}
}
} // End of bucket list
+ parIndex.markValid(true);
return parIndex;
}
}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListIndexCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListIndexCommand.java
index 847426c..c892c3c 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListIndexCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListIndexCommand.java
@@ -78,6 +78,7 @@ public class ListIndexCommand implements GfshCommand {
indexData.accumulate("Type", StringUtils.defaultString(indexDetails.getIndexType()));
indexData.accumulate("Indexed Expression", indexDetails.getIndexedExpression());
indexData.accumulate("From Clause", indexDetails.getFromClause());
+ indexData.accumulate("Valid Index", indexDetails.getIsValid());
if (showStats) {
final IndexStatisticsDetailsAdapter adapter =
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/IndexDetails.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/IndexDetails.java
index 335302e..8dc67b6 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/IndexDetails.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/domain/IndexDetails.java
@@ -18,6 +18,7 @@ package org.apache.geode.management.internal.cli.domain;
import org.apache.commons.lang.StringUtils;
import org.apache.geode.cache.query.Index;
import org.apache.geode.cache.query.IndexStatistics;
+import org.apache.geode.cache.query.internal.index.AbstractIndex;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.internal.lang.ObjectUtils;
@@ -36,6 +37,7 @@ import java.io.Serializable;
@SuppressWarnings("unused")
public class IndexDetails implements Comparable<IndexDetails>, Serializable {
+ private static final long serialVersionUID = -2198907141534201288L;
private IndexStatisticsDetails indexStatisticsDetails;
private IndexType indexType;
@@ -45,6 +47,7 @@ public class IndexDetails implements Comparable<IndexDetails>, Serializable {
private String projectionAttributes;
private String memberName;
private String regionName;
+ private String isValid;
private final String indexName;
private final String memberId;
@@ -84,12 +87,20 @@ public class IndexDetails implements Comparable<IndexDetails>, Serializable {
setMemberName(member.getName());
setProjectionAttributes(index.getProjectionAttributes());
setRegionName(index.getRegion().getName());
-
+ if (index instanceof AbstractIndex) {
+ setIsValid(((AbstractIndex) index).isValid());
+ } else {
+ setIsValid(false);
+ }
if (index.getStatistics() != null) {
setIndexStatisticsDetails(createIndexStatisticsDetails(index.getStatistics()));
}
}
+ public void setIsValid(boolean valid) {
+ this.isValid = String.valueOf(valid);
+ }
+
public IndexDetails(final String memberId, final String regionPath, final String indexName) {
assertValidArgument(StringUtils.isNotBlank(memberId),
"The member having a region with an index must be specified!");
@@ -175,6 +186,10 @@ public class IndexDetails implements Comparable<IndexDetails>, Serializable {
return regionPath;
}
+ public String getIsValid() {
+ return this.isValid;
+ }
+
public int compareTo(final IndexDetails indexDetails) {
int comparisonValue = compare(getMemberName(), indexDetails.getMemberName());
comparisonValue = (comparisonValue != 0 ? comparisonValue
@@ -223,6 +238,7 @@ public class IndexDetails implements Comparable<IndexDetails>, Serializable {
buffer.append(", memberName = ").append(getMemberName());
buffer.append(", regionName = ").append(getRegionName());
buffer.append(", regionPath = ").append(getRegionPath());
+ buffer.append(", isValid = ").append(getIsValid());
buffer.append(", projectAttributes = ").append(getProjectionAttributes());
buffer.append("}");
diff --git a/geode-core/src/test/java/org/apache/geode/cache/query/data/Portfolio.java b/geode-core/src/test/java/org/apache/geode/cache/query/data/Portfolio.java
index bc9874c..464a822 100644
--- a/geode-core/src/test/java/org/apache/geode/cache/query/data/Portfolio.java
+++ b/geode-core/src/test/java/org/apache/geode/cache/query/data/Portfolio.java
@@ -236,6 +236,10 @@ public class Portfolio implements Serializable, DataSerializable {
return this.doubleMinValue;
}
+ public void throwExceptionMethod() {
+ throw new IllegalStateException();
+ }
+
public void fromData(DataInput in) throws IOException, ClassNotFoundException {
this.ID = in.readInt();
boolean isNull = DataSerializer.readPrimitiveBoolean(in);
diff --git a/geode-core/src/test/java/org/apache/geode/cache/query/dunit/CorruptedIndexIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/cache/query/dunit/CorruptedIndexIntegrationTest.java
new file mode 100644
index 0000000..b7a3742
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/cache/query/dunit/CorruptedIndexIntegrationTest.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.cache.query.dunit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+import org.awaitility.Awaitility;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.DataPolicy;
+import org.apache.geode.cache.PartitionAttributesFactory;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.query.Index;
+import org.apache.geode.cache.query.QueryService;
+import org.apache.geode.cache.query.SelectResults;
+import org.apache.geode.cache.query.data.Portfolio;
+import org.apache.geode.cache.query.internal.QueryObserverAdapter;
+import org.apache.geode.cache.query.internal.QueryObserverHolder;
+import org.apache.geode.cache.query.internal.index.IndexProtocol;
+import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
+import org.apache.geode.test.junit.categories.DistributedTest;
+
+@Category(DistributedTest.class)
+public class CorruptedIndexIntegrationTest extends JUnit4CacheTestCase {
+
+ @Test
+ public void putMustSucceedAndIndexInvalidatedWhenAPutCorruptsAnIndex() throws Exception {
+
+ String queryString = "SELECT * FROM /REGION_NAME WHERE ID = 3";
+ String regionName = "REGION_NAME";
+
+ Cache cache = getCache();
+
+ Region region =
+ cache.createRegionFactory().setDataPolicy(DataPolicy.PARTITION).create(regionName);
+
+ QueryService queryService = cache.getQueryService();
+ Index idIndex = queryService.createIndex("idIndex", "ID", "/" + regionName);
+ Index exceptionIndex =
+ queryService.createIndex("exceptionIndex", "throwExceptionMethod", "/" + regionName);
+
+ IntStream.rangeClosed(1, 3).forEach(i -> region.put(i, new Portfolio(i)));
+
+
+ assertEquals("Uncorrupted index must have all the entries", 3,
+ idIndex.getStatistics().getNumberOfValues());
+ assertEquals("Corrupted index should not have indexed any entries", 0,
+ exceptionIndex.getStatistics().getNumberOfValues());
+
+ SelectResults results = (SelectResults) queryService.newQuery(queryString).execute();
+
+ assertEquals("Query execution must be successful ", 1, results.size());
+ }
+
+
+ @Test
+ public void indexCreationMustFailIfRegionEntriesAreNotCompatible() throws Exception {
+
+ String queryString = "SELECT * FROM /REGION_NAME WHERE ID = 3";
+ String regionName = "REGION_NAME";
+
+ Cache cache = getCache();
+
+ Region region =
+ cache.createRegionFactory().setDataPolicy(DataPolicy.PARTITION).create(regionName);
+
+ QueryService queryService = cache.getQueryService();
+
+ IntStream.rangeClosed(1, 3).forEach(i -> region.put(i, new Portfolio(i)));
+
+ Index idIndex = queryService.createIndex("idIndex", "ID", "/" + regionName);
+ try {
+ queryService.createIndex("exceptionIndex", "throwExceptionMethod", "/" + regionName);
+ fail();
+ } catch (Exception exception) {
+ System.out.println("Exception expected!");
+ }
+
+ assertEquals("Uncorrupted index must have all the entries ", 3,
+ idIndex.getStatistics().getNumberOfValues());
+
+ SelectResults results = (SelectResults) queryService.newQuery(queryString).execute();
+
+ assertEquals("Query execution must be successful ", 1, results.size());
+ }
+
+ class QueryObserverImpl extends QueryObserverAdapter {
+ boolean isIndexesUsed = false;
+
+ final ArrayList indexesUsed = new ArrayList();
+
+ public void beforeIndexLookup(Index index, int oper, Object key) {
+ indexesUsed.add(index.getName());
+ }
+
+ public void afterIndexLookup(Collection results) {
+ if (results != null) {
+ isIndexesUsed = true;
+ }
+ }
+
+ public void reset() {
+ this.isIndexesUsed = false;
+ this.indexesUsed.clear();
+ }
+ }
+
+ @Test
+ public void putMustSucceedWhenTheRangeIndexIsCorrupted() throws Exception {
+ String regionName = "portfolio";
+ String INDEX_NAME = "key_index1";
+
+ PartitionAttributesFactory partitionAttributes = new PartitionAttributesFactory();
+ partitionAttributes.setTotalNumBuckets(1);
+
+ Cache cache = getCache();
+ Region region = cache.createRegionFactory().setDataPolicy(DataPolicy.PARTITION)
+ .setPartitionAttributes(partitionAttributes.create()).create(regionName);
+
+ Portfolio p = new Portfolio(1, 2);
+ HashMap map1 = new HashMap();
+ map1.put("SUN", 1);
+ map1.put("IBM", 2);
+ map1.put("AOL", 4);
+ p.positions = map1;
+ region.put(1, p);
+
+ QueryService queryService = cache.getQueryService();
+ Index keyIndex1 = queryService.createIndex(INDEX_NAME, "positions[*]", "/portfolio");
+
+ Portfolio p2 = new Portfolio(3, 4);
+ HashMap map2 = new HashMap();
+ map2.put("APPL", 3);
+ map2.put("AOL", "hello");
+ p2.positions = map2;
+
+ region.put(2, p2);
+
+ assertEquals("Put must be successful", 2, region.size());
+
+
+ assertEquals("Index must be invalid at this point ", false, keyIndex1.isValid());
+
+ QueryObserverImpl observer = new QueryObserverImpl();
+ QueryObserverHolder.setInstance(observer);
+
+ SelectResults results = (SelectResults) queryService
+ .newQuery(
+ "select * from /portfolio p where p.positions['AOL'] = 'hello' OR p.positions['IBM'] = 2")
+ .execute();
+
+ assertEquals("Correct results expected from the query execution ", 2, results.size());
+
+ assertEquals("No index must be used while executing the query ", 0,
+ observer.indexesUsed.size());
+
+ }
+
+ @Test
+ public void rangeIndexCreationMustFailIfRegionEntriesAreNotCompatible() throws Exception {
+ String regionName = "portfolio";
+ String INDEX_NAME = "key_index1";
+
+ PartitionAttributesFactory partitionAttributes = new PartitionAttributesFactory();
+ partitionAttributes.setTotalNumBuckets(1);
+
+ Cache cache = getCache();
+ Region region = cache.createRegionFactory().setDataPolicy(DataPolicy.PARTITION)
+ .setPartitionAttributes(partitionAttributes.create()).create(regionName);
+
+ Portfolio p = new Portfolio(1, 2);
+ HashMap map1 = new HashMap();
+ map1.put("SUN", 1);
+ map1.put("IBM", 2);
+ map1.put("AOL", 4);
+ p.positions = map1;
+ region.put(1, p);
+
+ Portfolio p2 = new Portfolio(3, 4);
+ HashMap map2 = new HashMap();
+ map2.put("APPL", 3);
+ map2.put("AOL", "hello");
+ p2.positions = map2;
+
+ region.put(2, p2);
+
+ assertEquals("Put must be successful", 2, region.size());
+
+ QueryService queryService = cache.getQueryService();
+ try {
+ queryService.createIndex(INDEX_NAME, "positions[*]", "/portfolio");
+ fail();
+ } catch (Exception exception) {
+ System.out.println("Expected Exception " + exception);
+ }
+
+ assertEquals("There should be no index present", null,
+ queryService.getIndex(region, INDEX_NAME));
+
+ QueryObserverImpl observer = new QueryObserverImpl();
+ QueryObserverHolder.setInstance(observer);
+
+ SelectResults results = (SelectResults) queryService
+ .newQuery(
+ "select * from /portfolio p where p.positions['AOL'] = 'hello' OR p.positions['IBM'] = 2")
+ .execute();
+
+ assertEquals("Current results expected from the query execution ", 2, results.size());
+
+ assertEquals("No index must be used while executing the query ", 0,
+ observer.indexesUsed.size());
+
+ }
+
+ @Test
+ public void rangeIndexCreationMustPassIfEntriesArePresentInDifferentBucketsAndQueriesMustUseThem()
+ throws Exception {
+ String regionName = "portfolio";
+ String INDEX_NAME = "key_index1";
+
+
+ Cache cache = getCache();
+ Region region =
+ cache.createRegionFactory().setDataPolicy(DataPolicy.PARTITION).create(regionName);
+
+ Portfolio p = new Portfolio(1, 2);
+ HashMap map1 = new HashMap();
+ map1.put("SUN", 1);
+ map1.put("IBM", 2);
+ map1.put("AOL", 4);
+ p.positions = map1;
+ region.put(1, p);
+
+ Portfolio p2 = new Portfolio(3, 4);
+ HashMap map2 = new HashMap();
+ map2.put("APPL", 3);
+ map2.put("AOL", "hello");
+ p2.positions = map2;
+
+ region.put(2, p2);
+
+ assertEquals("Put must be successful", 2, region.size());
+
+ QueryService queryService = cache.getQueryService();
+
+ try {
+ Index keyIndex1 = queryService.createIndex(INDEX_NAME, "positions[*]", "/portfolio");
+ assertEquals("Index must be valid", true, keyIndex1.isValid());
+ } catch (Exception exception) {
+ fail();
+ }
+
+ QueryObserverImpl observer = new QueryObserverImpl();
+ QueryObserverHolder.setInstance(observer);
+
+ SelectResults results = (SelectResults) queryService
+ .newQuery(
+ "select * from /portfolio p where p.positions['AOL'] = 'hello' OR p.positions['IBM'] = 2")
+ .execute();
+
+ assertEquals("Current results expected from the query execution ", 2, results.size());
+
+ assertEquals("Index must be used while executing the query ", 2, observer.indexesUsed.size());
+
+ }
+
+
+}
diff --git a/geode-core/src/test/java/org/apache/geode/cache/query/transaction/QueryAndJtaJUnitTest.java b/geode-core/src/test/java/org/apache/geode/cache/query/transaction/QueryAndJtaJUnitTest.java
index b994733..5859806 100644
--- a/geode-core/src/test/java/org/apache/geode/cache/query/transaction/QueryAndJtaJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/cache/query/transaction/QueryAndJtaJUnitTest.java
@@ -419,32 +419,6 @@ public class QueryAndJtaJUnitTest {
}
}
- @Test
- public void testFailedIndexUpdateOnCommitForPut() throws Exception {
- Person.THROW_ON_INDEX = true;
- AttributesFactory af = new AttributesFactory();
- af.setDataPolicy(DataPolicy.REPLICATE);
- SimpleListener sl = new SimpleListener();
- af.setCacheListener(sl);
- Region region = cache.createRegion("sample", af.create());
- qs.createIndex("foo", IndexType.FUNCTIONAL, "index", "/sample");
- Context ctx = cache.getJNDIContext();
-
- Integer x = new Integer(0);
- region.getCache().getCacheTransactionManager().begin();
- region.create(x, new Person("xyz", 45));
- try {
- region.getCache().getCacheTransactionManager().commit();
- fail("commit should have thrown an exception because the index maintenance threw");
- } catch (org.apache.geode.cache.query.IndexMaintenanceException ie) {
- // this is the desired case
- }
- Person p = (Person) region.get(x);
- assertEquals("object shouldn't have made it into region", null, p);
- assertEquals(0, sl.creates);
- assertEquals(0, sl.updates);
- }
-
private static class SimpleListener extends CacheListenerAdapter {
public int creates = 0;
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsDUnitTest.java
index 415f6f7..383af2f 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsDUnitTest.java
@@ -111,6 +111,19 @@ public class IndexCommandsDUnitTest {
}
@Test
+ public void testListIndexValidField() throws Exception {
+ CommandStringBuilder createStringBuilder = new CommandStringBuilder(CliStrings.CREATE_INDEX);
+ createStringBuilder.addOption(CliStrings.CREATE_INDEX__NAME, indexName);
+ createStringBuilder.addOption(CliStrings.CREATE_INDEX__EXPRESSION, "\"h.low\"");
+ createStringBuilder.addOption(CliStrings.CREATE_INDEX__REGION,
+ "\"/" + partitionedRegionName + " s, s.history h\"");
+
+ gfsh.executeAndVerifyCommand(createStringBuilder.toString());
+
+ assertTrue(indexIsListedAsValid());
+ }
+
+ @Test
public void testCannotCreateIndexWithExistingIndexName() throws Exception {
createBaseIndexForTesting();
@@ -253,6 +266,11 @@ public class IndexCommandsDUnitTest {
return gfsh.getGfshOutput().contains(indexName);
}
+ private boolean indexIsListedAsValid() throws Exception {
+ gfsh.executeAndVerifyCommand(CliStrings.LIST_INDEX);
+ return gfsh.getGfshOutput().contains("true");
+ }
+
private static Region<?, ?> createPartitionedRegion(String regionName, Cache cache,
Class keyConstraint, Class valueConstraint) {
RegionFactory regionFactory = cache.createRegionFactory();
diff --git a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
index a588268..62fac3b 100755
--- a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
+++ b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
@@ -512,7 +512,7 @@ org/apache/geode/management/internal/cli/domain/DiskStoreDetails$RegionDetails,f
org/apache/geode/management/internal/cli/domain/DurableCqNamesResult,true,1,cqNames:java/util/List
org/apache/geode/management/internal/cli/domain/EvictionAttributesInfo,true,1,evictionAction:java/lang/String,evictionAlgorithm:java/lang/String,evictionMaxValue:int,nonDefaultAttributes:java/util/Map
org/apache/geode/management/internal/cli/domain/FixedPartitionAttributesInfo,true,1,isPrimary:boolean,numBuckets:int,partitionName:java/lang/String
-org/apache/geode/management/internal/cli/domain/IndexDetails,false,fromClause:java/lang/String,indexName:java/lang/String,indexStatisticsDetails:org/apache/geode/management/internal/cli/domain/IndexDetails$IndexStatisticsDetails,indexType:org/apache/geode/management/internal/cli/domain/IndexDetails$IndexType,indexedExpression:java/lang/String,memberId:java/lang/String,memberName:java/lang/String,projectionAttributes:java/lang/String,regionName:java/lang/String,regionPath:java/lang/String
+org/apache/geode/management/internal/cli/domain/IndexDetails,true,-2198907141534201288,fromClause:java/lang/String,indexName:java/lang/String,indexStatisticsDetails:org/apache/geode/management/internal/cli/domain/IndexDetails$IndexStatisticsDetails,indexType:org/apache/geode/management/internal/cli/domain/IndexDetails$IndexType,indexedExpression:java/lang/String,isValid:java/lang/String,memberId:java/lang/String,memberName:java/lang/String,projectionAttributes:java/lang/String,regionName [...]
org/apache/geode/management/internal/cli/domain/IndexDetails$IndexStatisticsDetails,false,numberOfKeys:java/lang/Long,numberOfUpdates:java/lang/Long,numberOfValues:java/lang/Long,totalUpdateTime:java/lang/Long,totalUses:java/lang/Long
org/apache/geode/management/internal/cli/domain/IndexDetails$IndexType,false,description:java/lang/String
org/apache/geode/management/internal/cli/domain/IndexInfo,true,1,indexName:java/lang/String,indexType:int,indexedExpression:java/lang/String,regionPath:java/lang/String
@@ -822,4 +822,4 @@ org/apache/geode/redis/internal/executor/list/ListExecutor$ListDirection,false
org/apache/geode/security/AuthenticationFailedException,true,-8202866472279088879
org/apache/geode/security/AuthenticationRequiredException,true,4675976651103154919
org/apache/geode/security/GemFireSecurityException,true,3814254578203076926,cause:java/lang/Throwable
-org/apache/geode/security/NotAuthorizedException,true,419215768216387745,principal:java/security/Principal
+org/apache/geode/security/NotAuthorizedException,true,419215768216387745,principal:java/security/Principal
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <co...@geode.apache.org>'].