IGNITE-1178 fix for NPE in GridCacheProcessor.onKernalStop(). Fixes #1517
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0b996e62 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0b996e62 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0b996e62 Branch: refs/heads/ignite-1192 Commit: 0b996e62119b316f9758da09623c722ec2fb7921 Parents: e670351 Author: voipp <[email protected]> Authored: Mon Mar 13 17:23:07 2017 +0300 Committer: Alexey Goncharuk <[email protected]> Committed: Mon Mar 13 17:23:07 2017 +0300 ---------------------------------------------------------------------- .../cache/GridCacheAffinityManager.java | 21 +++--- .../cache/GridCacheManagerAdapter.java | 2 +- .../processors/cache/GridCacheProcessor.java | 2 +- .../processors/query/GridQueryProcessor.java | 20 +++++- .../cache/IncorrectCacheTypeMetadataTest.java | 72 +++++++++++++++++++ .../cache/IncorrectQueryEntityTest.java | 75 ++++++++++++++++++++ .../IgniteCacheQuerySelfTestSuite.java | 4 ++ 7 files changed, 183 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/0b996e62/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java index 17c9319..621634c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java @@ -17,6 +17,11 @@ package org.apache.ignite.internal.processors.cache; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.UUID; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.binary.BinaryObject; @@ -33,12 +38,6 @@ import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteFuture; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.UUID; - /** * Cache affinity manager. */ @@ -88,10 +87,15 @@ public class GridCacheAffinityManager extends GridCacheManagerAdapter { * */ public void cancelFutures() { + if (!starting.get()) + // Ignoring attempt to stop manager that has never been started. + return; + IgniteCheckedException err = new IgniteCheckedException("Failed to wait for topology update, cache (or node) is stopping."); - aff.cancelFutures(err); + if (aff != null) + aff.cancelFutures(err); } /** {@inheritDoc} */ @@ -99,7 +103,8 @@ public class GridCacheAffinityManager extends GridCacheManagerAdapter { IgniteCheckedException err = new IgniteClientDisconnectedCheckedException(reconnectFut, "Failed to wait for topology update, client disconnected."); - aff.cancelFutures(err); + if (aff != null) + aff.cancelFutures(err); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/0b996e62/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheManagerAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheManagerAdapter.java index 8ad0ea8..ab965de 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheManagerAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheManagerAdapter.java @@ -34,7 +34,7 @@ public class GridCacheManagerAdapter<K, V> implements GridCacheManager<K, V> { protected IgniteLogger log; /** Starting flag. */ - private final AtomicBoolean starting = new AtomicBoolean(false); + protected final AtomicBoolean starting = new AtomicBoolean(false); /** {@inheritDoc} */ @Override public final void start(GridCacheContext<K, V> cctx) throws IgniteCheckedException { http://git-wip-us.apache.org/repos/asf/ignite/blob/0b996e62/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index 50e1379..b016883 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -63,7 +63,6 @@ import org.apache.ignite.configuration.NearCacheConfiguration; import org.apache.ignite.configuration.TransactionConfiguration; import org.apache.ignite.events.EventType; import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException; import org.apache.ignite.internal.IgniteComponentType; import org.apache.ignite.internal.IgniteInternalFuture; @@ -102,6 +101,7 @@ import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProces import org.apache.ignite.internal.processors.plugin.CachePluginManager; import org.apache.ignite.internal.processors.query.GridQueryProcessor; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; +import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; import org.apache.ignite.internal.util.F0; import org.apache.ignite.internal.util.future.GridCompoundFuture; import org.apache.ignite.internal.util.future.GridFinishedFuture; http://git-wip-us.apache.org/repos/asf/ignite/blob/0b996e62/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java index 17060fb..fddb8df 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java @@ -1653,14 +1653,28 @@ public class GridQueryProcessor extends GridProcessorAdapter { res = buildClassProperty(false, valCls, pathStr, resType, aliases, coCtx); if (res == null) - throw new IgniteCheckedException("Failed to initialize property '" + pathStr + "' of type '" + - resType.getName() + "' for key class '" + keyCls + "' and value class '" + valCls + "'. " + - "Make sure that one of these classes contains respective getter method or field."); + throw new IgniteCheckedException(propertyInitializationExceptionMessage(keyCls, valCls, pathStr, resType)); return res; } /** + * Exception message to compare in tests. + * + * @param keyCls key class + * @param valCls value class + * @param pathStr property name + * @param resType property type + * @return + */ + public static String propertyInitializationExceptionMessage(Class<?> keyCls, Class<?> valCls, String pathStr, + Class<?> resType) { + return "Failed to initialize property '" + pathStr + "' of type '" + + resType.getName() + "' for key class '" + keyCls + "' and value class '" + valCls + "'. " + + "Make sure that one of these classes contains respective getter method or field."; + } + + /** * @param key If this is a key property. * @param cls Source type class. * @param pathStr String representing path to the property. May contains dots '.' to identify nested fields. http://git-wip-us.apache.org/repos/asf/ignite/blob/0b996e62/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectCacheTypeMetadataTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectCacheTypeMetadataTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectCacheTypeMetadataTest.java new file mode 100644 index 0000000..4178cde --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectCacheTypeMetadataTest.java @@ -0,0 +1,72 @@ +/* + * 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.ignite.internal.processors.cache; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.apache.ignite.cache.CacheTypeMetadata; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.processors.query.GridQueryProcessor; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * A test for {@link CacheTypeMetadata} initialization with incorrect query field name + */ +public class IncorrectCacheTypeMetadataTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + CacheConfiguration dfltCacheCfg = defaultCacheConfiguration(); + + CacheTypeMetadata cacheTypeMetadata = new CacheTypeMetadata(); + + Map<String, Class<?>> queryFieldsMap = new HashMap<>(); + + queryFieldsMap.put("exceptionOid", Object.class); + + cacheTypeMetadata.setQueryFields(queryFieldsMap); + cacheTypeMetadata.setValueType(Object.class); + + dfltCacheCfg.setTypeMetadata(Collections.singleton(cacheTypeMetadata)); + + cfg.setCacheConfiguration(dfltCacheCfg); + + return cfg; + } + + /** + * Grid must be stopped with property initialization exception. + * + * @throws Exception If failed. + */ + public void testIncorrectQueryField() throws Exception { + try { + startGrid(); + } + catch (Exception exception) { + if (!exception.getMessage().contains( + GridQueryProcessor.propertyInitializationExceptionMessage( + Object.class, Object.class, "exceptionOid", Object.class))) { + fail("property initialization exception must be thrown, but got " + exception.getMessage()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0b996e62/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectQueryEntityTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectQueryEntityTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectQueryEntityTest.java new file mode 100644 index 0000000..5d89a58 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IncorrectQueryEntityTest.java @@ -0,0 +1,75 @@ +/* + * 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.ignite.internal.processors.cache; + +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Set; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.processors.query.GridQueryProcessor; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +public class IncorrectQueryEntityTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + CacheConfiguration dfltCacheCfg = defaultCacheConfiguration(); + + QueryEntity queryEntity = new QueryEntity(Object.class.getName(), Object.class.getName()); + + LinkedHashMap<String, String> fields = new LinkedHashMap<>(); + + fields.put("exceptionOid", Object.class.getName()); + + queryEntity.setFields(fields); + + Set<String> keyFields = new HashSet<>(); + + keyFields.add("exceptionOid"); + + queryEntity.setKeyFields(keyFields); + + dfltCacheCfg.setQueryEntities(F.asList(queryEntity)); + + cfg.setCacheConfiguration(dfltCacheCfg); + + return cfg; + } + + /** + * Grid must be stopped with property initialization exception. + * + * @throws Exception If failed. + */ + public void testIncorrectQueryField() throws Exception { + try { + startGrid(); + } + catch (Exception exception) { + if (!exception.getMessage().contains( + GridQueryProcessor.propertyInitializationExceptionMessage( + Object.class, Object.class, "exceptionOid", Object.class))) { + fail("property initialization exception must be thrown, but got " + exception.getMessage()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0b996e62/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java index 0c74f12..b7be713 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java @@ -68,6 +68,8 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheQueryIndexSelfTest import org.apache.ignite.internal.processors.cache.IgniteCacheQueryLoadSelfTest; import org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest; import org.apache.ignite.internal.processors.cache.IgniteCrossCachesJoinsQueryTest; +import org.apache.ignite.internal.processors.cache.IncorrectCacheTypeMetadataTest; +import org.apache.ignite.internal.processors.cache.IncorrectQueryEntityTest; import org.apache.ignite.internal.processors.cache.QueryEntityCaseMismatchTest; import org.apache.ignite.internal.processors.cache.SqlFieldsQuerySelfTest; import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicFieldsQuerySelfTest; @@ -133,6 +135,8 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite { // Config. suite.addTestSuite(IgniteCacheDuplicateEntityConfigurationSelfTest.class); + suite.addTestSuite(IncorrectCacheTypeMetadataTest.class); + suite.addTestSuite(IncorrectQueryEntityTest.class); // Queries tests. suite.addTestSuite(IgniteSqlSplitterSelfTest.class);
