You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2018/01/17 10:35:17 UTC

[05/17] ignite git commit: IEP-4 Baseline topology for persistent caches (Phase 1) Contributed by: Dmitriy Govorukhin Dmitry Pavlov Eduard Shangareev Ily

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/internal/visor/baseline/VisorBaselineTaskResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/baseline/VisorBaselineTaskResult.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/baseline/VisorBaselineTaskResult.java
new file mode 100644
index 0000000..a3559bd
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/baseline/VisorBaselineTaskResult.java
@@ -0,0 +1,144 @@
+/*
+ * 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.visor.baseline;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+import org.apache.ignite.cluster.BaselineNode;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.VisorDataTransferObject;
+
+/**
+ * Result for {@link VisorBaselineTask}.
+ */
+public class VisorBaselineTaskResult extends VisorDataTransferObject {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Cluster state. */
+    private boolean active;
+
+    /** Current topology version. */
+    private long topVer;
+
+    /** Current baseline nodes. */
+    private Map<String, VisorBaselineNode> baseline;
+
+    /** Current server nodes. */
+    private Map<String, VisorBaselineNode> servers;
+
+    /**
+     * Default constructor.
+     */
+    public VisorBaselineTaskResult() {
+        // No-op.
+    }
+
+    /**
+     * @param nodes Nodes to process.
+     * @return Map of DTO objects.
+     */
+    private static Map<String, VisorBaselineNode> toMap(Collection<? extends BaselineNode> nodes) {
+        if (F.isEmpty(nodes))
+            return null;
+
+        Map<String, VisorBaselineNode> map = new TreeMap<>();
+
+        for (BaselineNode node : nodes) {
+            VisorBaselineNode dto = new VisorBaselineNode(node);
+
+            map.put(dto.getConsistentId(), dto);
+        }
+
+        return map;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param active Cluster state.
+     * @param topVer Current topology version.
+     * @param baseline Current baseline nodes.
+     * @param servers Current server nodes.
+     */
+    public VisorBaselineTaskResult(
+        boolean active,
+        long topVer,
+        Collection<? extends BaselineNode> baseline,
+        Collection<? extends BaselineNode> servers) {
+        this.active = active;
+        this.topVer = topVer;
+        this.baseline = toMap(baseline);
+        this.servers = toMap(servers);
+    }
+
+    /**
+     * @return Cluster state.
+     */
+    public boolean isActive() {
+        return active;
+    }
+
+    /**
+     * @return Current topology version.
+     */
+    public long getTopologyVersion() {
+        return topVer;
+    }
+
+    /**
+     * @return Baseline nodes.
+     */
+    public Map<String, VisorBaselineNode> getBaseline() {
+        return baseline;
+    }
+
+    /**
+     * @return Server nodes.
+     */
+    public Map<String, VisorBaselineNode> getServers() {
+        return servers;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+        out.writeBoolean(active);
+        out.writeLong(topVer);
+        U.writeMap(out, baseline);
+        U.writeMap(out, servers);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException {
+        active = in.readBoolean();
+        topVer = in.readLong();
+        baseline = U.readTreeMap(in);
+        servers = U.readTreeMap(in);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorBaselineTaskResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
index 48c3abb..4e41537 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
@@ -301,6 +301,9 @@ public class VisorGatewayTask implements ComputeTask<Object[], Object> {
                 return res;
             }
 
+            if (cls.isEnum())
+                return Enum.valueOf(cls, val);
+
             return val;
         }
 
@@ -360,10 +363,11 @@ public class VisorGatewayTask implements ComputeTask<Object[], Object> {
                             // Length of arguments that required to constructor by influence of nested complex objects.
                             int needArgs = args;
 
-                            for (Class type: types)
+                            for (Class type: types) {
                                 // When constructor required specified types increase length of required arguments.
                                 if (TYPE_ARG_LENGTH.containsKey(type))
                                     needArgs += TYPE_ARG_LENGTH.get(type);
+                            }
 
                             if (needArgs == beanArgsCnt) {
                                 Object[] initArgs = new Object[args];

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
index 07ba214..1754cc8 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
@@ -54,6 +54,7 @@ import org.apache.ignite.plugin.extensions.communication.MessageWriter;
 import org.apache.ignite.plugin.security.SecuritySubject;
 import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.resources.LoggerResource;
+import org.apache.ignite.spi.discovery.DiscoveryDataBag;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK;
@@ -899,6 +900,11 @@ public abstract class IgniteSpiAdapter implements IgniteSpi {
         }
 
         /** {@inheritDoc} */
+        @Nullable @Override public IgniteNodeValidationResult validateNode(ClusterNode node, DiscoveryDataBag discoData) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
         @Override public Collection<SecuritySubject> authenticatedSubjects() {
             return Collections.emptyList();
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
index 96b3e61..108c4d4 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiContext.java
@@ -31,6 +31,7 @@ import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.plugin.extensions.communication.MessageFactory;
 import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
 import org.apache.ignite.plugin.security.SecuritySubject;
+import org.apache.ignite.spi.discovery.DiscoveryDataBag;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -296,6 +297,12 @@ public interface IgniteSpiContext {
     @Nullable public IgniteNodeValidationResult validateNode(ClusterNode node);
 
     /**
+     * @param node Node.
+     * @param discoData Disco data.
+     */
+    @Nullable public IgniteNodeValidationResult validateNode(ClusterNode node, DiscoveryDataBag discoData);
+
+    /**
      * Gets collection of authenticated subjects together with their permissions.
      *
      * @return Collection of authenticated subjects.

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
index b9f381b..6f79720 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
@@ -3574,36 +3574,43 @@ class ServerImpl extends TcpDiscoveryImpl {
                     }
                 }
 
-                final IgniteNodeValidationResult err = spi.getSpiContext().validateNode(node);
+                IgniteNodeValidationResult err;
+
+                err = spi.getSpiContext().validateNode(node);
+
+                if (err == null)
+                    err = spi.getSpiContext().validateNode(node, msg.gridDiscoveryData().unmarshalJoiningNodeData(spi.marshaller(), U.resolveClassLoader(spi.ignite().configuration()), false, log));
 
                 if (err != null) {
+                    final IgniteNodeValidationResult err0 = err;
+
                     if (log.isDebugEnabled())
                         log.debug("Node validation failed [res=" + err + ", node=" + node + ']');
 
                     utilityPool.execute(
                         new Runnable() {
                             @Override public void run() {
-                                boolean ping = node.id().equals(err.nodeId()) ? pingNode(node) : pingNode(err.nodeId());
+                                boolean ping = node.id().equals(err0.nodeId()) ? pingNode(node) : pingNode(err0.nodeId());
 
                                 if (!ping) {
                                     if (log.isDebugEnabled())
                                         log.debug("Conflicting node has already left, need to wait for event. " +
                                             "Will ignore join request for now since it will be recent [req=" + msg +
-                                            ", err=" + err.message() + ']');
+                                            ", err=" + err0.message() + ']');
 
                                     // Ignore join request.
                                     return;
                                 }
 
-                                LT.warn(log, err.message());
+                                LT.warn(log, err0.message());
 
                                 // Always output in debug.
                                 if (log.isDebugEnabled())
-                                    log.debug(err.message());
+                                    log.debug(err0.message());
 
                                 try {
                                     trySendMessageDirectly(node,
-                                        new TcpDiscoveryCheckFailedMessage(err.nodeId(), err.sendMessage()));
+                                        new TcpDiscoveryCheckFailedMessage(err0.nodeId(), err0.sendMessage()));
                                 }
                                 catch (IgniteSpiException e) {
                                     if (log.isDebugEnabled())

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
index 3b83b2e..713bbab 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
@@ -972,17 +972,23 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements DiscoverySpi {
 
             initAddresses();
 
-            final Serializable cfgId = ignite.configuration().getConsistentId();
+            IgniteConfiguration cfg = ignite.configuration();
+
+            final Serializable cfgId = cfg.getConsistentId();
 
             if (cfgId == null) {
-                final List<String> sortedAddrs = new ArrayList<>(addrs.get1());
+                if (cfg.isClientMode() == Boolean.TRUE)
+                    consistentId = cfg.getNodeId();
+                else {
+                    List<String> sortedAddrs = new ArrayList<>(addrs.get1());
 
-                Collections.sort(sortedAddrs);
+                    Collections.sort(sortedAddrs);
 
-                if (getBoolean(IGNITE_CONSISTENT_ID_BY_HOST_WITHOUT_PORT))
-                    consistentId = U.consistentId(sortedAddrs);
-                else
-                    consistentId = U.consistentId(sortedAddrs, impl.boundPort());
+                    if (getBoolean(IGNITE_CONSISTENT_ID_BY_HOST_WITHOUT_PORT))
+                        consistentId = U.consistentId(sortedAddrs);
+                    else
+                        consistentId = U.consistentId(sortedAddrs, impl.boundPort());
+                }
             }
             else
                 consistentId = cfgId;

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/DiscoveryDataPacket.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/DiscoveryDataPacket.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/DiscoveryDataPacket.java
index 1134de6..5f70f3c 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/DiscoveryDataPacket.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/DiscoveryDataPacket.java
@@ -48,6 +48,9 @@ public class DiscoveryDataPacket implements Serializable {
     private Map<Integer, byte[]> joiningNodeData = new HashMap<>();
 
     /** */
+    private transient Map<Integer, Serializable> unmarshalledJoiningNodeData;
+
+    /** */
     private Map<Integer, byte[]> commonData = new HashMap<>();
 
     /** */
@@ -154,14 +157,14 @@ public class DiscoveryDataPacket implements Serializable {
         DiscoveryDataBag dataBag = new DiscoveryDataBag(joiningNodeId);
 
         if (joiningNodeData != null && !joiningNodeData.isEmpty()) {
-            Map<Integer, Serializable> unmarshJoiningNodeData = unmarshalData(
+            unmarshalledJoiningNodeData = unmarshalData(
                     joiningNodeData,
                     marsh,
                     clsLdr,
                     clientNode,
                     log);
 
-            dataBag.joiningNodeData(unmarshJoiningNodeData);
+            dataBag.joiningNodeData(unmarshalledJoiningNodeData);
         }
 
         return dataBag;
@@ -340,6 +343,11 @@ public class DiscoveryDataPacket implements Serializable {
      * (e.g. on nodes prior in cluster to the one where this method is called).
      */
     public DiscoveryDataBag bagForDataCollection() {
-        return new DiscoveryDataBag(joiningNodeId, commonData.keySet());
+        DiscoveryDataBag dataBag = new DiscoveryDataBag(joiningNodeId, commonData.keySet());
+
+        if (unmarshalledJoiningNodeData != null)
+            dataBag.joiningNodeData(unmarshalledJoiningNodeData);
+
+        return dataBag;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
index 38c2a1b..01534f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
@@ -623,8 +623,6 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Cluste
 
         Object consistentIdAttr = attrs.get(ATTR_NODE_CONSISTENT_ID);
 
-        consistentId = consistentIdAttr != null ? consistentIdAttr : U.consistentId(addrs, discPort);
-
         // Cluster metrics
         byte[] mtr = U.readByteArray(in);
 
@@ -648,6 +646,11 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Cluste
         intOrder = in.readLong();
         ver = (IgniteProductVersion)in.readObject();
         clientRouterNodeId = U.readUuid(in);
+
+        if (isClient())
+            consistentId = consistentIdAttr != null ? consistentIdAttr : id;
+        else
+            consistentId = consistentIdAttr != null ? consistentIdAttr : U.consistentId(addrs, discPort);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/main/resources/META-INF/classnames.properties
----------------------------------------------------------------------
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index c27681e..cb70857 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -209,7 +209,6 @@ org.apache.ignite.internal.GridKernalGatewayImpl
 org.apache.ignite.internal.GridKernalState
 org.apache.ignite.internal.GridLoggerProxy
 org.apache.ignite.internal.GridMessageListenHandler
-org.apache.ignite.internal.GridNodeOrderComparator
 org.apache.ignite.internal.GridTaskCancelRequest
 org.apache.ignite.internal.GridTaskNameHashKey
 org.apache.ignite.internal.GridTaskSessionRequest
@@ -302,6 +301,8 @@ org.apache.ignite.internal.cluster.IgniteClusterImpl
 org.apache.ignite.internal.cluster.IgniteClusterImpl$1
 org.apache.ignite.internal.cluster.IgniteKillTask
 org.apache.ignite.internal.cluster.IgniteKillTask$IgniteKillJob
+org.apache.ignite.internal.cluster.NodeOrderComparator
+org.apache.ignite.internal.cluster.NodeOrderLegacyComparator
 org.apache.ignite.internal.compute.ComputeTaskCancelledCheckedException
 org.apache.ignite.internal.compute.ComputeTaskTimeoutCheckedException
 org.apache.ignite.internal.direct.DirectMessageReader$1
@@ -311,6 +312,14 @@ org.apache.ignite.internal.executor.GridExecutorService
 org.apache.ignite.internal.executor.GridExecutorService$1
 org.apache.ignite.internal.executor.GridExecutorService$TaskTerminateListener
 org.apache.ignite.internal.igfs.common.IgfsIpcCommand
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl$1
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl$BooleanProperty
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl$ConnectionProperty
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl$IntegerProperty
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl$NumberProperty
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl$PropertyValidator
+org.apache.ignite.internal.jdbc.thin.ConnectionPropertiesImpl$StringProperty
 org.apache.ignite.internal.jdbc2.JdbcBatchUpdateTask
 org.apache.ignite.internal.jdbc2.JdbcConnection$JdbcConnectionValidationTask
 org.apache.ignite.internal.jdbc2.JdbcDatabaseMetadata$UpdateMetadataTask
@@ -335,11 +344,14 @@ org.apache.ignite.internal.managers.deployment.GridDeploymentResponse
 org.apache.ignite.internal.managers.discovery.CustomMessageWrapper
 org.apache.ignite.internal.managers.discovery.DiscoCache$1
 org.apache.ignite.internal.managers.discovery.DiscoCache$2
+org.apache.ignite.internal.managers.discovery.DiscoCache$3
 org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$1
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$2
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$4$1
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$6
+org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$8
+org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$9
 org.apache.ignite.internal.managers.discovery.GridLocalMetrics
 org.apache.ignite.internal.managers.eventstorage.GridEventStorageMessage
 org.apache.ignite.internal.managers.indexing.GridIndexingManager$1
@@ -351,6 +363,7 @@ org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl$Segment
 org.apache.ignite.internal.pagemem.wal.StorageException
 org.apache.ignite.internal.pagemem.wal.WALIterator
 org.apache.ignite.internal.pagemem.wal.WALPointer
+org.apache.ignite.internal.pagemem.wal.record.ExchangeRecord$Type
 org.apache.ignite.internal.pagemem.wal.record.WALRecord$RecordType
 org.apache.ignite.internal.pagemem.wal.record.delta.DeltaApplicationException
 org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion
@@ -414,6 +427,7 @@ org.apache.ignite.internal.processors.cache.CacheObjectImpl
 org.apache.ignite.internal.processors.cache.CacheOperationContext
 org.apache.ignite.internal.processors.cache.CacheOperationFilter
 org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException
+org.apache.ignite.internal.processors.cache.CacheStatisticsModeChangeMessage
 org.apache.ignite.internal.processors.cache.CacheStoppedException
 org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException
 org.apache.ignite.internal.processors.cache.CacheType
@@ -436,9 +450,9 @@ org.apache.ignite.internal.processors.cache.GridCacheAdapter$12
 org.apache.ignite.internal.processors.cache.GridCacheAdapter$13
 org.apache.ignite.internal.processors.cache.GridCacheAdapter$14
 org.apache.ignite.internal.processors.cache.GridCacheAdapter$15
-org.apache.ignite.internal.processors.cache.GridCacheAdapter$16$1
+org.apache.ignite.internal.processors.cache.GridCacheAdapter$16
 org.apache.ignite.internal.processors.cache.GridCacheAdapter$17
-org.apache.ignite.internal.processors.cache.GridCacheAdapter$18
+org.apache.ignite.internal.processors.cache.GridCacheAdapter$18$1
 org.apache.ignite.internal.processors.cache.GridCacheAdapter$2
 org.apache.ignite.internal.processors.cache.GridCacheAdapter$26$1
 org.apache.ignite.internal.processors.cache.GridCacheAdapter$28
@@ -529,10 +543,12 @@ org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$Ex
 org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$1
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$10
+org.apache.ignite.internal.processors.cache.GridCacheProcessor$11
+org.apache.ignite.internal.processors.cache.GridCacheProcessor$2
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$3
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$4
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$5
-org.apache.ignite.internal.processors.cache.GridCacheProcessor$7
+org.apache.ignite.internal.processors.cache.GridCacheProcessor$6
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$8
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$9
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$LocalAffinityFunction
@@ -555,6 +571,7 @@ org.apache.ignite.internal.processors.cache.GridCacheUtils$18
 org.apache.ignite.internal.processors.cache.GridCacheUtils$19
 org.apache.ignite.internal.processors.cache.GridCacheUtils$2
 org.apache.ignite.internal.processors.cache.GridCacheUtils$20
+org.apache.ignite.internal.processors.cache.GridCacheUtils$22
 org.apache.ignite.internal.processors.cache.GridCacheUtils$3
 org.apache.ignite.internal.processors.cache.GridCacheUtils$4
 org.apache.ignite.internal.processors.cache.GridCacheUtils$5
@@ -562,6 +579,7 @@ org.apache.ignite.internal.processors.cache.GridCacheUtils$6
 org.apache.ignite.internal.processors.cache.GridCacheUtils$7
 org.apache.ignite.internal.processors.cache.GridCacheUtils$8
 org.apache.ignite.internal.processors.cache.GridCacheUtils$9
+org.apache.ignite.internal.processors.cache.GridCacheUtils$BackupPostProcessingClosure
 org.apache.ignite.internal.processors.cache.GridCacheValueCollection
 org.apache.ignite.internal.processors.cache.GridCacheValueCollection$1
 org.apache.ignite.internal.processors.cache.GridChangeGlobalStateMessageResponse
@@ -898,12 +916,13 @@ org.apache.ignite.internal.processors.cache.local.atomic.GridLocalAtomicCache$5
 org.apache.ignite.internal.processors.cache.local.atomic.GridLocalAtomicCache$8
 org.apache.ignite.internal.processors.cache.local.atomic.GridLocalAtomicCache$9
 org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter$RowData
-org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager$6
-org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager$9
+org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager$11
+org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager$7
 org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager$CheckpointEntryType
 org.apache.ignite.internal.processors.cache.persistence.GridCacheOffheapManager$RebalanceIteratorAdapter
 org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager$1
 org.apache.ignite.internal.processors.cache.persistence.file.AsyncFileIOFactory
+org.apache.ignite.internal.processors.cache.persistence.file.FileDownloader$1
 org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory
 org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory
 org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl$Segment
@@ -914,10 +933,16 @@ org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$DestroyBa
 org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Result
 org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO$EntryPart
 org.apache.ignite.internal.processors.cache.persistence.wal.AbstractWalRecordsIterator
+org.apache.ignite.internal.processors.cache.persistence.wal.AbstractWalRecordsIterator$StartSeekingFilter
 org.apache.ignite.internal.processors.cache.persistence.wal.FileWALPointer
 org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager$FileArchiver$1
+org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager$FileArchiver$2
+org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager$FileCompressor$1
 org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager$RecordsIterator
 org.apache.ignite.internal.processors.cache.persistence.wal.SegmentEofException
+org.apache.ignite.internal.processors.cache.persistence.wal.SegmentedRingByteBuffer$BufferMode
+org.apache.ignite.internal.processors.cache.persistence.wal.SingleSegmentLogicalRecordsIterator
+org.apache.ignite.internal.processors.cache.persistence.wal.SingleSegmentLogicalRecordsIterator$LogicalRecordsFilter
 org.apache.ignite.internal.processors.cache.persistence.wal.WalSegmentTailReachedException
 org.apache.ignite.internal.processors.cache.persistence.wal.crc.IgniteDataIntegrityViolationException
 org.apache.ignite.internal.processors.cache.persistence.wal.reader.StandaloneWalRecordsIterator
@@ -1049,6 +1074,15 @@ org.apache.ignite.internal.processors.cache.transactions.TxLock
 org.apache.ignite.internal.processors.cache.transactions.TxLockList
 org.apache.ignite.internal.processors.cache.transactions.TxLocksRequest
 org.apache.ignite.internal.processors.cache.transactions.TxLocksResponse
+org.apache.ignite.internal.processors.cache.verify.CollectConflictPartitionKeysTask
+org.apache.ignite.internal.processors.cache.verify.CollectConflictPartitionKeysTask$CollectPartitionEntryHashesJob
+org.apache.ignite.internal.processors.cache.verify.PartitionEntryHashRecord
+org.apache.ignite.internal.processors.cache.verify.PartitionHashRecord
+org.apache.ignite.internal.processors.cache.verify.PartitionKey
+org.apache.ignite.internal.processors.cache.verify.RetrieveConflictPartitionValuesTask
+org.apache.ignite.internal.processors.cache.verify.RetrieveConflictPartitionValuesTask$RetrieveConflictValuesJob
+org.apache.ignite.internal.processors.cache.verify.VerifyBackupPartitionsTask
+org.apache.ignite.internal.processors.cache.verify.VerifyBackupPartitionsTask$VerifyBackupPartitionsJob
 org.apache.ignite.internal.processors.cache.version.GridCacheRawVersionedEntry
 org.apache.ignite.internal.processors.cache.version.GridCacheVersion
 org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext$State
@@ -1075,6 +1109,10 @@ org.apache.ignite.internal.processors.closure.GridClosureProcessor$T8
 org.apache.ignite.internal.processors.closure.GridClosureProcessor$T9
 org.apache.ignite.internal.processors.closure.GridClosureProcessor$TaskNoReduceAdapter
 org.apache.ignite.internal.processors.closure.GridPeerDeployAwareTaskAdapter
+org.apache.ignite.internal.processors.cluster.BaselineTopology
+org.apache.ignite.internal.processors.cluster.BaselineTopologyHistory
+org.apache.ignite.internal.processors.cluster.BaselineTopologyHistoryItem
+org.apache.ignite.internal.processors.cluster.BranchingPointType
 org.apache.ignite.internal.processors.cluster.ChangeGlobalStateFinishMessage
 org.apache.ignite.internal.processors.cluster.ChangeGlobalStateMessage
 org.apache.ignite.internal.processors.cluster.ClusterProcessor$3
@@ -1086,6 +1124,7 @@ org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor$3
 org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor$4
 org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor$5
 org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor$7
+org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor$BaselineStateAndHistoryData
 org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor$CheckGlobalStateComputeRequest
 org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor$ClientChangeGlobalStateComputeRequest
 org.apache.ignite.internal.processors.continuous.AbstractContinuousMessage
@@ -1388,6 +1427,7 @@ org.apache.ignite.internal.processors.query.schema.message.SchemaProposeDiscover
 org.apache.ignite.internal.processors.query.schema.operation.SchemaAbstractAlterTableOperation
 org.apache.ignite.internal.processors.query.schema.operation.SchemaAbstractOperation
 org.apache.ignite.internal.processors.query.schema.operation.SchemaAlterTableAddColumnOperation
+org.apache.ignite.internal.processors.query.schema.operation.SchemaAlterTableDropColumnOperation
 org.apache.ignite.internal.processors.query.schema.operation.SchemaIndexAbstractOperation
 org.apache.ignite.internal.processors.query.schema.operation.SchemaIndexCreateOperation
 org.apache.ignite.internal.processors.query.schema.operation.SchemaIndexDropOperation
@@ -1621,6 +1661,7 @@ org.apache.ignite.internal.util.lang.GridAbsClosure
 org.apache.ignite.internal.util.lang.GridAbsClosureX
 org.apache.ignite.internal.util.lang.GridCloseableIterator
 org.apache.ignite.internal.util.lang.GridClosureException
+org.apache.ignite.internal.util.lang.GridFunc$1
 org.apache.ignite.internal.util.lang.GridIterable
 org.apache.ignite.internal.util.lang.GridIterableAdapter
 org.apache.ignite.internal.util.lang.GridIterableAdapter$IteratorWrapper
@@ -1727,6 +1768,7 @@ org.apache.ignite.internal.util.snaptree.EpochNode
 org.apache.ignite.internal.util.snaptree.EpochNode$Child
 org.apache.ignite.internal.util.snaptree.SnapTreeMap
 org.apache.ignite.internal.util.snaptree.SnapTreeMap$SubMap
+org.apache.ignite.internal.util.tostring.SBLimitedLength
 org.apache.ignite.internal.util.typedef.C1
 org.apache.ignite.internal.util.typedef.C2
 org.apache.ignite.internal.util.typedef.CA
@@ -1767,6 +1809,12 @@ org.apache.ignite.internal.visor.VisorJob
 org.apache.ignite.internal.visor.VisorMultiNodeTask
 org.apache.ignite.internal.visor.VisorOneNodeTask
 org.apache.ignite.internal.visor.VisorTaskArgument
+org.apache.ignite.internal.visor.baseline.VisorBaselineNode
+org.apache.ignite.internal.visor.baseline.VisorBaselineOperation
+org.apache.ignite.internal.visor.baseline.VisorBaselineTask
+org.apache.ignite.internal.visor.baseline.VisorBaselineTask$VisorBaselineJob
+org.apache.ignite.internal.visor.baseline.VisorBaselineTaskArg
+org.apache.ignite.internal.visor.baseline.VisorBaselineTaskResult
 org.apache.ignite.internal.visor.binary.VisorBinaryMetadata
 org.apache.ignite.internal.visor.binary.VisorBinaryMetadataCollectorTask
 org.apache.ignite.internal.visor.binary.VisorBinaryMetadataCollectorTask$VisorBinaryCollectMetadataJob
@@ -1802,7 +1850,7 @@ org.apache.ignite.internal.visor.cache.VisorCacheMetricsCollectorTask
 org.apache.ignite.internal.visor.cache.VisorCacheMetricsCollectorTask$VisorCacheMetricsCollectorJob
 org.apache.ignite.internal.visor.cache.VisorCacheMetricsCollectorTaskArg
 org.apache.ignite.internal.visor.cache.VisorCacheModifyTask
-org.apache.ignite.internal.visor.cache.VisorCacheModifyTask$VisorCacheClearJob
+org.apache.ignite.internal.visor.cache.VisorCacheModifyTask$VisorCacheModifyJob
 org.apache.ignite.internal.visor.cache.VisorCacheModifyTaskArg
 org.apache.ignite.internal.visor.cache.VisorCacheModifyTaskResult
 org.apache.ignite.internal.visor.cache.VisorCacheNearConfiguration
@@ -2057,23 +2105,23 @@ org.apache.ignite.spi.checkpoint.sharedfs.SharedFsCheckpointData
 org.apache.ignite.spi.collision.jobstealing.JobStealingRequest
 org.apache.ignite.spi.collision.priorityqueue.PriorityQueueCollisionSpi$PriorityGridCollisionJobContextComparator
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$1
+org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$10
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$11
-org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$12
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$2$1
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$2$2
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$2$ConnectClosure
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$2$ConnectClosure$1
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$2$ConnectClosureNew
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$2$ConnectClosureNew$1
+org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$3
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$4
-org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$5
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$HandshakeClosure
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$HandshakeException
-org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$HandshakeMessage
-org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$HandshakeMessage2
 org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$HandshakeTimeoutException
-org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$NodeIdMessage
-org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi$RecoveryLastReceivedMessage
+org.apache.ignite.spi.communication.tcp.messages.HandshakeMessage
+org.apache.ignite.spi.communication.tcp.messages.HandshakeMessage2
+org.apache.ignite.spi.communication.tcp.messages.NodeIdMessage
+org.apache.ignite.spi.communication.tcp.messages.RecoveryLastReceivedMessage
 org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage
 org.apache.ignite.spi.discovery.tcp.ClientImpl$State
 org.apache.ignite.spi.discovery.tcp.ServerImpl$IpFinderCleaner$1

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
index 1c10bf1..518e674 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
@@ -1024,7 +1024,11 @@ public class IgniteClientReconnectCacheTest extends IgniteClientReconnectAbstrac
         List<IgniteCache> caches = new ArrayList<>();
 
         for (int i = 0; i < CLIENTS; i++) {
-            Ignite client = startGrid(SRV_CNT + i);
+            int g = SRV_CNT + i;
+
+            IgniteEx client = startGrid(g);
+
+            info(">>>>> Started client: " + g);
 
             addListener(client, disconnectLatch, reconnectLatch);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
index faa19dc..11f19b2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
@@ -156,7 +156,7 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
      * @throws Exception If failed.
      */
     public void testPutAndRemove() throws Exception {
-        putAndRemove(DUR, null, null);
+        putAndRemove(duration(), null, null);
     }
 
     /**
@@ -166,7 +166,7 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
         if (atomicityMode() != CacheAtomicityMode.TRANSACTIONAL)
             return;
 
-        putAndRemove(30_000, PESSIMISTIC, REPEATABLE_READ);
+        putAndRemove(duration(), PESSIMISTIC, REPEATABLE_READ);
     }
 
     /**
@@ -176,7 +176,12 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
         if (atomicityMode() != CacheAtomicityMode.TRANSACTIONAL)
             return;
 
-        putAndRemove(30_000, OPTIMISTIC, SERIALIZABLE);
+        putAndRemove(duration(), OPTIMISTIC, SERIALIZABLE);
+    }
+
+    /** */
+    protected long duration() {
+        return DUR;
     }
 
     /**
@@ -314,29 +319,7 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
             }
         });
 
-        IgniteInternalFuture<?> killFut = GridTestUtils.runAsync(new Callable<Void>() {
-            @Override public Void call() throws Exception {
-                Thread.currentThread().setName("restart-thread");
-
-                while (!stop.get()) {
-                    U.sleep(random(KILL_DELAY.get1(), KILL_DELAY.get2()));
-
-                    killAndRestart(stop);
-
-                    CyclicBarrier barrier = cmp.get();
-
-                    if (barrier != null) {
-                        log.info("Wait data check.");
-
-                        barrier.await(60_000, TimeUnit.MILLISECONDS);
-
-                        log.info("Finished wait data check.");
-                    }
-                }
-
-                return null;
-            }
-        });
+        IgniteInternalFuture killFut = createAndRunConcurrentAction(stop, cmp);
 
         try {
             long stopTime = duration + U.currentTimeMillis() ;
@@ -408,25 +391,50 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
         log.info("Test finished. Update errors: " + errCntr.get());
     }
 
+    /** */
+    protected IgniteInternalFuture createAndRunConcurrentAction(final AtomicBoolean stop, final AtomicReference<CyclicBarrier> cmp) {
+        return GridTestUtils.runAsync(new Callable<Void>() {
+            @Override public Void call() throws Exception {
+                Thread.currentThread().setName("restart-thread");
+
+                while (!stop.get()) {
+                    U.sleep(random(KILL_DELAY.get1(), KILL_DELAY.get2()));
+
+                    killAndRestart(stop, random(1, GRID_CNT + 1));
+
+                    CyclicBarrier barrier = cmp.get();
+
+                    if (barrier != null) {
+                        log.info("Wait data check.");
+
+                        barrier.await(60_000, TimeUnit.MILLISECONDS);
+
+                        log.info("Finished wait data check.");
+                    }
+                }
+
+                return null;
+            }
+        });
+    }
+
     /**
      * @param stop Stop flag.
      * @throws Exception If failed.
      */
-    private void killAndRestart(AtomicBoolean stop) throws Exception {
+    protected void killAndRestart(AtomicBoolean stop, int nodeIdx) throws Exception {
         if (stop.get())
             return;
 
-        int idx = random(1, GRID_CNT + 1);
-
-        log.info("Killing node " + idx);
+        log.info("Killing node " + nodeIdx);
 
-        stopGrid(idx);
+        stopGrid(nodeIdx);
 
         U.sleep(random(START_DELAY.get1(), START_DELAY.get2()));
 
-        log.info("Restarting node " + idx);
+        log.info("Restarting node " + nodeIdx);
 
-        startGrid(idx);
+        startGrid(nodeIdx);
 
         if (stop.get())
             return;
@@ -475,7 +483,7 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
      * @param max Max possible value (exclusive).
      * @return Random value.
      */
-    private static int random(int min, int max) {
+    protected static int random(int min, int max) {
         if (max == min)
             return max;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractSelfTest.java
index 81aadb9..df93ae4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractSelfTest.java
@@ -34,7 +34,6 @@ import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CachePeekMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
-import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
@@ -113,7 +112,7 @@ public abstract class GridCacheAbstractSelfTest extends GridCommonAbstractTest {
      *
      * @throws IgniteCheckedException If failed.
      */
-    void initStoreStrategy() throws IgniteCheckedException {
+    protected void initStoreStrategy() throws IgniteCheckedException {
         if (storeStgy == null)
             storeStgy = isMultiJvm() ? new H2CacheStoreStrategy() : new MapCacheStoreStrategy();
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
index 3d1b014..e40700d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
@@ -459,7 +459,7 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
         @Nullable GridCacheVersion dhtVer,
         @Nullable Long updateCntr)
         throws IgniteCheckedException, GridCacheEntryRemovedException {
-        return new GridCacheUpdateTxResult(true, rawPut(val, ttl));
+        return new GridCacheUpdateTxResult(true, rawPut(val, ttl), null);
     }
 
     /** {@inheritDoc} */
@@ -545,7 +545,7 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
 
         val = null;
 
-        return new GridCacheUpdateTxResult(true, old);
+        return new GridCacheUpdateTxResult(true, old, null);
     }
 
     /** @inheritDoc */

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
index 1827c65..267cb18 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -34,6 +35,7 @@ import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.WALMode;
 import org.apache.ignite.internal.IgniteClientReconnectAbstractTest;
+import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.TestRecordingCommunicationSpi;
@@ -784,7 +786,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
         startWithCaches1(SRVS, CLIENTS);
 
         final Ignite srv = ignite(0);
-        Ignite client = ignite(SRVS);
+        IgniteEx client = grid(SRVS);
 
         if (persistenceEnabled())
             ignite(0).active(true);
@@ -822,12 +824,11 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
             }
         });
 
-        checkCache(client, CACHE_NAME_PREFIX + 0, false);
-
         if (transition) {
             assertFalse(stateFut.get().isDone());
 
-            assertFalse(client.active());
+            // Public API method would block forever because we blocked the exchange message.
+            assertFalse(client.context().state().publicApiActiveState(false));
 
             spi1.waitForBlocked();
 
@@ -889,7 +890,7 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
         startWithCaches1(SRVS, CLIENTS);
 
         final Ignite srv = ignite(0);
-        Ignite client = ignite(SRVS);
+        IgniteEx client = grid(SRVS);
 
         checkNoCaches(SRVS + CLIENTS);
 
@@ -922,12 +923,10 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
             }
         });
 
-        checkCache(client, CACHE_NAME_PREFIX + 0, !transition);
-
         if (transition) {
             assertFalse(stateFut.get().isDone());
 
-            assertFalse(client.active());
+            assertTrue(client.context().state().clusterState().transition());
 
             spi1.waitForBlocked();
 
@@ -1140,70 +1139,6 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
     }
 
     /**
-     * @throws Exception If failed.
-     */
-    public void testActivateFailover3() throws Exception {
-        stateChangeFailover3(true);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testDeactivateFailover3() throws Exception {
-        stateChangeFailover3(false);
-    }
-
-    /**
-     * @param activate If {@code true} tests activation, otherwise deactivation.
-     * @throws Exception If failed.
-     */
-    private void stateChangeFailover3(boolean activate) throws Exception {
-        testDiscoSpi = true;
-
-        startNodesAndBlockStatusChange(4, 0, 0, !activate);
-
-        client = false;
-
-        IgniteInternalFuture startFut1 = GridTestUtils.runAsync(new Callable() {
-            @Override public Object call() throws Exception {
-                startGrid(4);
-
-                return null;
-            }
-        }, "start-node1");
-
-        IgniteInternalFuture startFut2 = GridTestUtils.runAsync(new Callable() {
-            @Override public Object call() throws Exception {
-                startGrid(5);
-
-                return null;
-            }
-        }, "start-node2");
-
-        U.sleep(1000);
-
-        // Stop all nodes participating in state change and not allow last node to finish exchange.
-        for (int i = 0; i < 4; i++)
-            ((TestTcpDiscoverySpi)ignite(i).configuration().getDiscoverySpi()).simulateNodeFailure();
-
-        for (int i = 0; i < 4; i++)
-            stopGrid(getTestIgniteInstanceName(i), true, false);
-
-        startFut1.get();
-        startFut2.get();
-
-        assertFalse(ignite(4).active());
-        assertFalse(ignite(5).active());
-
-        ignite(4).active(true);
-
-        for (int i = 0; i < 4; i++)
-            startGrid(i);
-
-        checkCaches1(6);
-    }
-
-    /**
      * @param exp If {@code true} there should be recorded messages.
      */
     private void checkRecordedMessages(boolean exp) {
@@ -1274,7 +1209,11 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
      * @param node Node.
      * @param exp {@code True} if expect that cache is started on node.
      */
-    void checkCache(Ignite node, String cacheName, boolean exp) {
+    void checkCache(Ignite node, String cacheName, boolean exp) throws IgniteCheckedException {
+        ((IgniteEx)node).context().cache().context().exchange().lastTopologyFuture().get();
+
+        ((IgniteEx)node).context().state().publicApiActiveState(true);
+
         GridCacheAdapter cache = ((IgniteKernal)node).context().cache().internalCache(cacheName);
 
         if (exp)
@@ -1288,6 +1227,8 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
      */
     final void checkNoCaches(int nodes) {
         for (int i = 0; i < nodes; i++) {
+            grid(i).context().state().publicApiActiveState(true);
+
             GridCacheProcessor cache = ((IgniteKernal)ignite(i)).context().cache();
 
             assertTrue(cache.caches().isEmpty());

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTestWithPersistence.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTestWithPersistence.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTestWithPersistence.java
index 15e67b2..76078bc 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTestWithPersistence.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTestWithPersistence.java
@@ -20,10 +20,14 @@ package org.apache.ignite.internal.processors.cache;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.concurrent.CountDownLatch;
 import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.testframework.GridTestUtils;
@@ -51,6 +55,11 @@ public class IgniteClusterActivateDeactivateTestWithPersistence extends IgniteCl
         GridTestUtils.deleteDbFiles();
     }
 
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        return super.getConfiguration(igniteInstanceName).setAutoActivationEnabled(false);
+    }
+
     /**
      * @throws Exception If failed.
      */
@@ -79,12 +88,8 @@ public class IgniteClusterActivateDeactivateTestWithPersistence extends IgniteCl
         activateCachesRestore(5, true);
     }
 
-    /**
-     * @param srvs Number of server nodes.
-     * @param withNewCaches If {@code true} then after restart has new caches in configuration.
-     * @throws Exception If failed.
-     */
-    private void activateCachesRestore(int srvs, boolean withNewCaches) throws Exception {
+    /** */
+    private Map<Integer, Integer> startGridsAndLoadData(int srvs) throws Exception {
         Ignite srv = startGrids(srvs);
 
         srv.active(true);
@@ -101,6 +106,17 @@ public class IgniteClusterActivateDeactivateTestWithPersistence extends IgniteCl
             }
         }
 
+        return cacheData;
+    }
+
+    /**
+     * @param srvs Number of server nodes.
+     * @param withNewCaches If {@code true} then after restart has new caches in configuration.
+     * @throws Exception If failed.
+     */
+    private void activateCachesRestore(int srvs, boolean withNewCaches) throws Exception {
+        Map<Integer, Integer> cacheData = startGridsAndLoadData(srvs);
+
         stopAllGrids();
 
         for (int i = 0; i < srvs; i++) {
@@ -110,7 +126,7 @@ public class IgniteClusterActivateDeactivateTestWithPersistence extends IgniteCl
             startGrid(i);
         }
 
-        srv = ignite(0);
+        Ignite srv = ignite(0);
 
         checkNoCaches(srvs);
 
@@ -160,6 +176,47 @@ public class IgniteClusterActivateDeactivateTestWithPersistence extends IgniteCl
     }
 
     /**
+     * @see <a href="https://issues.apache.org/jira/browse/IGNITE-7330">IGNITE-7330</a> for more information about context of the test
+     */
+    public void testClientJoinsWhenActivationIsInProgress() throws Exception {
+        startGridsAndLoadData(5);
+
+        stopAllGrids();
+
+        Ignite srv = startGrids(5);
+
+        final CountDownLatch clientStartLatch = new CountDownLatch(1);
+
+        IgniteInternalFuture clStartFut = GridTestUtils.runAsync(new Runnable() {
+            @Override public void run() {
+                try {
+                    clientStartLatch.await();
+
+                    Thread.sleep(10);
+
+                    client = true;
+
+                    Ignite cl = startGrid("client0");
+
+                    IgniteCache<Object, Object> atomicCache = cl.cache(CACHE_NAME_PREFIX + '0');
+                    IgniteCache<Object, Object> txCache = cl.cache(CACHE_NAME_PREFIX + '1');
+
+                    assertEquals(100, atomicCache.size());
+                    assertEquals(100, txCache.size());
+                }
+                catch (Exception e) {
+                    log.error("Error occurred", e);
+                }
+            }
+        }, "client-starter-thread");
+
+        clientStartLatch.countDown();
+        srv.active(true);
+
+        clStartFut.get();
+    }
+
+    /**
      * Checks that persistent caches are present with actual data and volatile caches are missing.
      *
      * @param cacheData Cache data.
@@ -214,8 +271,4 @@ public class IgniteClusterActivateDeactivateTestWithPersistence extends IgniteCl
 
         checkNoCaches(SRVS);
     }
-
-    @Override public void testActivateFailover3() throws Exception {
-        super.testActivateFailover3();
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheBaselineTopologyTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheBaselineTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheBaselineTopologyTest.java
new file mode 100644
index 0000000..5fbd752
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheBaselineTopologyTest.java
@@ -0,0 +1,711 @@
+/*
+ * 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.distributed;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.PartitionLossPolicy;
+import org.apache.ignite.cluster.BaselineNode;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.internal.util.typedef.PA;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.cache.PartitionLossPolicy.READ_ONLY_SAFE;
+
+/**
+ *
+ */
+public class CacheBaselineTopologyTest extends GridCommonAbstractTest {
+    /** */
+    private static final String CACHE_NAME = "cache";
+
+    /** */
+    private boolean client;
+
+    /** */
+    private static final int NODE_COUNT = 4;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        GridTestUtils.deleteDbFiles();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+
+        GridTestUtils.deleteDbFiles();
+
+        client = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        cfg.setDataStorageConfiguration(
+            new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration()
+                    .setPersistenceEnabled(true)
+                    .setMaxSize(100 * 1024 * 1024)
+                    .setInitialSize(100 * 1024 * 1024)
+            )
+            .setWalMode(WALMode.LOG_ONLY)
+        );
+
+        if (client)
+            cfg.setClientMode(true);
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTopologyChangesWithFixedBaseline() throws Exception {
+        startGrids(NODE_COUNT);
+
+        IgniteEx ignite = grid(0);
+
+        ignite.active(true);
+
+        awaitPartitionMapExchange();
+
+        Map<ClusterNode, Ignite> nodes = new HashMap<>();
+
+        for (int i = 0; i < NODE_COUNT; i++) {
+            Ignite ig = grid(i);
+
+            nodes.put(ig.cluster().localNode(), ig);
+        }
+
+        IgniteCache<Integer, Integer> cache =
+            ignite.createCache(
+                new CacheConfiguration<Integer, Integer>()
+                    .setName(CACHE_NAME)
+                    .setCacheMode(PARTITIONED)
+                    .setBackups(1)
+                    .setPartitionLossPolicy(READ_ONLY_SAFE)
+            );
+
+        int key = -1;
+
+        for (int k = 0; k < 100_000; k++) {
+            if (!ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(k).contains(ignite.localNode())) {
+                key = k;
+                break;
+            }
+        }
+
+        assert key >= 0;
+
+        int part = ignite.affinity(CACHE_NAME).partition(key);
+
+        Collection<ClusterNode> initialMapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping.size() == 2 : initialMapping;
+
+        ignite.cluster().setBaselineTopology(baselineNodes(nodes.keySet()));
+
+        awaitPartitionMapExchange();
+
+        cache.put(key, 1);
+
+        Collection<ClusterNode> mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping.size() == mapping.size() : mapping;
+        assert initialMapping.containsAll(mapping) : mapping;
+
+        IgniteEx newIgnite = startGrid(4);
+
+        awaitPartitionMapExchange();
+
+        mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping.size() == mapping.size() : mapping;
+        assert initialMapping.containsAll(mapping) : mapping;
+
+        mapping = newIgnite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping.size() == mapping.size() : mapping;
+        assert initialMapping.containsAll(mapping) : mapping;
+
+        Set<String> stoppedNodeNames = new HashSet<>();
+
+        ClusterNode node = mapping.iterator().next();
+
+        stoppedNodeNames.add(nodes.get(node).name());
+
+        nodes.get(node).close();
+
+        nodes.remove(node);
+
+        awaitPartitionMapExchange(true, true, null);
+
+        mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert mapping.size() == 1 : mapping;
+        assert initialMapping.containsAll(mapping);
+
+        node = mapping.iterator().next();
+
+        stoppedNodeNames.add(nodes.get(node).name());
+
+        nodes.get(node).close();
+
+        nodes.remove(node);
+
+        awaitPartitionMapExchange();
+
+        mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert mapping.isEmpty() : mapping;
+
+        GridDhtPartitionTopology topology = ignite.cachex(CACHE_NAME).context().topology();
+
+        assert topology.lostPartitions().contains(part);
+
+        for (String nodeName : stoppedNodeNames) {
+            startGrid(nodeName);
+        }
+
+        assert ignite.cluster().nodes().size() == NODE_COUNT + 1;
+
+        mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping.size() == mapping.size() : mapping;
+
+        for (ClusterNode n1 : initialMapping) {
+            boolean found = false;
+
+            for (ClusterNode n2 : mapping) {
+                if (n2.consistentId().equals(n1.consistentId())) {
+                    found = true;
+
+                    break;
+                }
+            }
+
+            assert found;
+        }
+
+        ignite.resetLostPartitions(Collections.singleton(CACHE_NAME));
+
+        cache.put(key, 2);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testBaselineTopologyChangesFromServer() throws Exception {
+        testBaselineTopologyChanges(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testBaselineTopologyChangesFromClient() throws Exception {
+        testBaselineTopologyChanges(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void testBaselineTopologyChanges(boolean fromClient) throws Exception {
+        startGrids(NODE_COUNT);
+
+        IgniteEx ignite;
+
+        if (fromClient) {
+            client = true;
+
+            ignite = startGrid(NODE_COUNT + 10);
+
+            client = false;
+        }
+        else
+            ignite = grid(0);
+
+        ignite.active(true);
+
+        awaitPartitionMapExchange();
+
+        Map<ClusterNode, Ignite> nodes = new HashMap<>();
+
+        for (int i = 0; i < NODE_COUNT; i++) {
+            Ignite ig = grid(i);
+
+            nodes.put(ig.cluster().localNode(), ig);
+        }
+
+        IgniteCache<Integer, Integer> cache =
+            ignite.createCache(
+                new CacheConfiguration<Integer, Integer>()
+                    .setName(CACHE_NAME)
+                    .setCacheMode(PARTITIONED)
+                    .setBackups(1)
+                    .setPartitionLossPolicy(READ_ONLY_SAFE)
+            );
+
+        int key = -1;
+
+        for (int k = 0; k < 100_000; k++) {
+            if (!ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(k).contains(ignite.localNode())) {
+                key = k;
+                break;
+            }
+        }
+
+        assert key >= 0;
+
+        int part = ignite.affinity(CACHE_NAME).partition(key);
+
+        Collection<ClusterNode> initialMapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping.size() == 2 : initialMapping;
+
+        ignite.cluster().setBaselineTopology(baselineNodes(nodes.keySet()));
+
+        Set<String> stoppedNodeNames = new HashSet<>();
+
+        ClusterNode node = initialMapping.iterator().next();
+
+        stoppedNodeNames.add(nodes.get(node).name());
+
+        nodes.get(node).close();
+
+        nodes.remove(node);
+
+        awaitPartitionMapExchange();
+
+        Collection<ClusterNode> mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert mapping.size() == 1 : mapping;
+        assert initialMapping.containsAll(mapping);
+
+        Set<ClusterNode> blt2 = new HashSet<>(ignite.cluster().nodes());
+
+        ignite.cluster().setBaselineTopology(baselineNodes(blt2));
+
+        awaitPartitionMapExchange();
+
+        Collection<ClusterNode> initialMapping2 = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping2.size() == 2 : initialMapping2;
+
+        Ignite newIgnite = startGrid(NODE_COUNT);
+
+        awaitPartitionMapExchange();
+
+        mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert mapping.size() == initialMapping2.size() : mapping;
+        assert mapping.containsAll(initialMapping2);
+
+        assert ignite.affinity(CACHE_NAME).primaryPartitions(newIgnite.cluster().localNode()).length == 0;
+
+        Set<ClusterNode> blt3 = new HashSet<>(ignite.cluster().nodes());
+
+        ignite.cluster().setBaselineTopology(baselineNodes(blt3));
+
+        awaitPartitionMapExchange();
+
+        Collection<ClusterNode> initialMapping3 = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert initialMapping3.size() == 2;
+
+        assert ignite.affinity(CACHE_NAME).primaryPartitions(newIgnite.cluster().localNode()).length > 0;
+
+        newIgnite = startGrid(NODE_COUNT + 1);
+
+        awaitPartitionMapExchange();
+
+        mapping = ignite.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert mapping.size() == initialMapping3.size() : mapping;
+        assert mapping.containsAll(initialMapping3);
+
+        assert ignite.affinity(CACHE_NAME).primaryPartitions(newIgnite.cluster().localNode()).length == 0;
+
+        ignite.cluster().setBaselineTopology(null);
+
+        awaitPartitionMapExchange();
+
+        assert ignite.affinity(CACHE_NAME).primaryPartitions(newIgnite.cluster().localNode()).length > 0;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPrimaryLeft() throws Exception {
+        startGrids(NODE_COUNT);
+
+        IgniteEx ig = grid(0);
+
+        ig.cluster().active(true);
+
+        awaitPartitionMapExchange();
+
+        IgniteCache<Integer, Integer> cache =
+            ig.createCache(
+                new CacheConfiguration<Integer, Integer>()
+                    .setName(CACHE_NAME)
+                    .setCacheMode(PARTITIONED)
+                    .setBackups(1)
+                    .setPartitionLossPolicy(READ_ONLY_SAFE)
+                    .setReadFromBackup(true)
+                    .setWriteSynchronizationMode(FULL_SYNC)
+                    .setRebalanceDelay(-1)
+            );
+
+        int key = 1;
+
+        List<ClusterNode> affNodes = (List<ClusterNode>) ig.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert affNodes.size() == 2;
+
+        int primaryIdx = -1;
+
+        IgniteEx primary = null;
+        IgniteEx backup = null;
+
+        for (int i = 0; i < NODE_COUNT; i++) {
+            if (grid(i).localNode().equals(affNodes.get(0))) {
+                primaryIdx = i;
+                primary = grid(i);
+            }
+            else if (grid(i).localNode().equals(affNodes.get(1)))
+                backup = grid(i);
+        }
+
+        assert primary != null;
+        assert backup != null;
+
+        Integer val1 = 1;
+        Integer val2 = 2;
+
+        cache.put(key, val1);
+
+        assertEquals(val1, primary.cache(CACHE_NAME).get(key));
+        assertEquals(val1, backup.cache(CACHE_NAME).get(key));
+
+        if (ig == primary) {
+            ig = backup;
+
+            cache = ig.cache(CACHE_NAME);
+        }
+
+        primary.close();
+
+        assertEquals(backup.localNode(), ig.affinity(CACHE_NAME).mapKeyToNode(key));
+
+        cache.put(key, val2);
+
+        assertEquals(val2, backup.cache(CACHE_NAME).get(key));
+
+        primary = startGrid(primaryIdx);
+
+        assertEquals(backup.localNode(), ig.affinity(CACHE_NAME).mapKeyToNode(key));
+
+        primary.cache(CACHE_NAME).rebalance().get();
+
+        awaitPartitionMapExchange();
+
+        assertEquals(primary.localNode(), ig.affinity(CACHE_NAME).mapKeyToNode(key));
+
+        assertEquals(val2, primary.cache(CACHE_NAME).get(key));
+        assertEquals(val2, backup.cache(CACHE_NAME).get(key));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPrimaryLeftAndClusterRestart() throws Exception {
+        startGrids(NODE_COUNT);
+
+        IgniteEx ig = grid(0);
+
+        ig.active(true);
+
+        IgniteCache<Integer, Integer> cache =
+            ig.createCache(
+                new CacheConfiguration<Integer, Integer>()
+                    .setName(CACHE_NAME)
+                    .setWriteSynchronizationMode(FULL_SYNC)
+                    .setCacheMode(PARTITIONED)
+                    .setBackups(1)
+                    .setPartitionLossPolicy(READ_ONLY_SAFE)
+                    .setReadFromBackup(true)
+                    .setRebalanceDelay(-1)
+            );
+
+        int key = 1;
+
+        List<ClusterNode> affNodes = (List<ClusterNode>) ig.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assert affNodes.size() == 2;
+
+        int primaryIdx = -1;
+        int backupIdx = -1;
+
+        IgniteEx primary = null;
+        IgniteEx backup = null;
+
+        for (int i = 0; i < NODE_COUNT; i++) {
+            if (grid(i).localNode().equals(affNodes.get(0))) {
+                primaryIdx = i;
+                primary = grid(i);
+            }
+            else if (grid(i).localNode().equals(affNodes.get(1))) {
+                backupIdx = i;
+                backup = grid(i);
+            }
+        }
+
+        assert primary != null;
+        assert backup != null;
+
+        Integer val1 = 1;
+        Integer val2 = 2;
+
+        cache.put(key, val1);
+
+        assertEquals(val1, primary.cache(CACHE_NAME).get(key));
+        assertEquals(val1, backup.cache(CACHE_NAME).get(key));
+
+        if (ig == primary) {
+            ig = backup;
+
+            cache = ig.cache(CACHE_NAME);
+        }
+
+        stopGrid(primaryIdx, false);
+
+        assertEquals(backup.localNode(), ig.affinity(CACHE_NAME).mapKeyToNode(key));
+
+        cache.put(key, val2);
+
+        assertEquals(val2, backup.cache(CACHE_NAME).get(key));
+
+        stopAllGrids(false);
+
+        startGrids(NODE_COUNT);
+
+        ig = grid(0);
+        primary = grid(primaryIdx);
+        backup = grid(backupIdx);
+
+        boolean activated = GridTestUtils.waitForCondition(new GridAbsPredicate() {
+            @Override public boolean apply() {
+                for (int i = 0; i < NODE_COUNT; i++)
+                  if (!grid(i).active())
+                      return false;
+
+                return true;
+            }
+        }, 10_000);
+
+        assert activated;
+
+//        assertEquals(backup.localNode(), ig.affinity(CACHE_NAME).mapKeyToNode(key));
+
+        assertEquals(val2, primary.cache(CACHE_NAME).get(key));
+        assertEquals(val2, backup.cache(CACHE_NAME).get(key));
+
+        primary.cache(CACHE_NAME).rebalance().get();
+
+        affNodes = (List<ClusterNode>) ig.affinity(CACHE_NAME).mapKeyToPrimaryAndBackups(key);
+
+        assertEquals(primary.localNode(), affNodes.get(0));
+        assertEquals(backup.localNode(), affNodes.get(1));
+
+        assertEquals(val2, primary.cache(CACHE_NAME).get(key));
+        assertEquals(val2, backup.cache(CACHE_NAME).get(key));
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void testMetadataUpdate() throws Exception {
+        startGrids(5);
+
+        Ignite ignite3 = grid(3);
+
+        ignite3.active(true);
+
+        CacheConfiguration<Object, Object> repCacheCfg = new CacheConfiguration<>("replicated")
+            .setCacheMode(CacheMode.REPLICATED)
+            .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+
+        IgniteCache<Object, Object> cache = ignite3.getOrCreateCache(repCacheCfg);
+
+        stopGrid(0);
+        stopGrid(1);
+        stopGrid(2);
+        stopGrid(4);
+
+        for (int i = 0; i < 100; i++)
+            cache.put(i, new TestValue(i));
+
+        stopAllGrids();
+
+        startGrids(5);
+
+        GridTestUtils.waitForCondition(new PA() {
+            @Override
+            public boolean apply() {
+                return grid(0).cluster().active();
+            }
+        }, getTestTimeout());
+
+        for (int g = 0; g < 5; g++) {
+            for (int i = 0; i < 100; i++)
+                assertEquals(new TestValue(i), grid(g).cache("replicated").get(i));
+        }
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void testClusterRestoredOnRestart() throws Exception {
+        startGrids(5);
+
+        Ignite ignite3 = grid(3);
+
+        ignite3.active(true);
+
+        stopGrid(0);
+
+        CacheConfiguration<Object, Object> cacheConfiguration = new CacheConfiguration<>("unknown_cache");
+
+        cacheConfiguration.setBackups(3);
+
+        IgniteCache<Object, Object> cache0 = ignite3.getOrCreateCache(cacheConfiguration);
+
+        for (int i = 0; i < 2048; i++)
+            cache0.put(i, 0);
+
+        awaitPartitionMapExchange();
+
+        stopAllGrids();
+
+        startGrids(5);
+
+        GridTestUtils.waitForCondition(new PA() {
+            @Override
+            public boolean apply() {
+                return grid(0).cluster().active();
+            }
+        }, getTestTimeout());
+
+        for (int g = 0; g < 5; g++) {
+            for (int i = 0; i < 2048; i++)
+                assertEquals("For key: " + i, 0, grid(g).cache("unknown_cache").get(i));
+        }
+    }
+
+    /** */
+    private Collection<BaselineNode> baselineNodes(Collection<ClusterNode> clNodes) {
+        Collection<BaselineNode> res = new ArrayList<>(clNodes.size());
+
+        for (ClusterNode clN : clNodes)
+            res.add(clN);
+
+        return res;
+    }
+
+    /**
+     *
+     */
+    private static class TestValue {
+        /** */
+        int f1;
+
+        /** */
+        int f2;
+
+        /** */
+        int f3;
+
+        /** */
+        int f4;
+
+        /**
+         * @param a Init value.
+         */
+        private TestValue(int a) {
+            f1 = f2 = f3 = f4 = a;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (!(o instanceof TestValue))
+                return false;
+
+            TestValue other = (TestValue)o;
+
+            return
+                f1 == other.f1 &&
+                f2 == other.f2 &&
+                f3 == other.f3 &&
+                f4 == other.f4;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            int result = f1;
+
+            result = 31 * result + f2;
+            result = 31 * result + f3;
+            result = 31 * result + f4;
+
+            return result;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheExchangeMergeTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheExchangeMergeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheExchangeMergeTest.java
index f93d60c..9660a76 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheExchangeMergeTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheExchangeMergeTest.java
@@ -82,6 +82,7 @@ import static org.apache.ignite.cache.CacheMode.PARTITIONED;
 import static org.apache.ignite.cache.CacheMode.REPLICATED;
 import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 import static org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT;
+import static org.apache.ignite.testframework.GridTestUtils.mergeExchangeWaitVersion;
 
 /**
  *
@@ -1178,15 +1179,6 @@ public class CacheExchangeMergeTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @param node Node.
-     * @param topVer Ready exchange version to wait for before trying to merge exchanges.
-     */
-    private void mergeExchangeWaitVersion(Ignite node, long topVer) {
-        ((IgniteKernal)node).context().cache().context().exchange().mergeExchangesTestWaitVersion(
-            new AffinityTopologyVersion(topVer, 0));
-    }
-
-    /**
      * @throws Exception If failed.
      */
     private void checkCaches() throws Exception {

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLateAffinityAssignmentTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLateAffinityAssignmentTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLateAffinityAssignmentTest.java
index ab07611..0704dbd 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLateAffinityAssignmentTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLateAffinityAssignmentTest.java
@@ -53,7 +53,8 @@ import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.internal.GridKernalContext;
-import org.apache.ignite.internal.GridNodeOrderComparator;
+import org.apache.ignite.internal.cluster.NodeOrderComparator;
+import org.apache.ignite.internal.cluster.NodeOrderLegacyComparator;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.IgniteNodeAttributes;
@@ -2852,7 +2853,7 @@ public class CacheLateAffinityAssignmentTest extends GridCommonAbstractTest {
                     affNodes.add(n);
             }
 
-            Collections.sort(affNodes, GridNodeOrderComparator.INSTANCE);
+            Collections.sort(affNodes, NodeOrderComparator.getInstance());
 
             AffinityFunctionContext affCtx = new GridAffinityFunctionContextImpl(
                 affNodes,

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePutAllFailoverAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePutAllFailoverAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePutAllFailoverAbstractTest.java
index 9a0fb03..57a150f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePutAllFailoverAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePutAllFailoverAbstractTest.java
@@ -125,21 +125,7 @@ public abstract class CachePutAllFailoverAbstractTest extends GridCacheAbstractS
 
         final long endTime = System.currentTimeMillis() + TEST_TIME;
 
-        IgniteInternalFuture<Object> restartFut = GridTestUtils.runAsync(new Callable<Object>() {
-            @Override public Object call() throws Exception {
-                Thread.currentThread().setName("restart-thread");
-
-                while (!finished.get() && System.currentTimeMillis() < endTime) {
-                    startGrid(NODE_CNT);
-
-                    U.sleep(500);
-
-                    stopGrid(NODE_CNT);
-                }
-
-                return null;
-            }
-        });
+        IgniteInternalFuture<Object> restartFut = createAndRunConcurrentAction(finished, endTime);
 
         try {
             final IgniteCache<TestKey, TestValue> cache = ignite(0).cache(DEFAULT_CACHE_NAME);
@@ -235,6 +221,25 @@ public abstract class CachePutAllFailoverAbstractTest extends GridCacheAbstractS
         }
     }
 
+    /** */
+    protected IgniteInternalFuture createAndRunConcurrentAction(final AtomicBoolean finished, final long endTime) {
+        return GridTestUtils.runAsync(new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                Thread.currentThread().setName("restart-thread");
+
+                while (!finished.get() && System.currentTimeMillis() < endTime) {
+                    startGrid(NODE_CNT);
+
+                    U.sleep(500);
+
+                    stopGrid(NODE_CNT);
+                }
+
+                return null;
+            }
+        });
+    }
+
     /**
      *
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/6f7aba85/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
index 86c0fa4..34bd0a0 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
@@ -32,6 +32,7 @@ import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.CI2;
+import org.apache.ignite.internal.util.typedef.PA;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -298,6 +299,12 @@ public class IgniteOptimisticTxSuspendResumeTest extends GridCommonAbstractTest
                         }
                     }).get(FUT_TIMEOUT);
 
+                    assertTrue(GridTestUtils.waitForCondition(new PA() {
+                        @Override public boolean apply() {
+                            return tx.state() == ROLLED_BACK;
+                        }
+                    }, getTestTimeout()));
+
                     assertEquals(ROLLED_BACK, tx.state());
 
                     assertFalse(cache.containsKey(1));
@@ -442,6 +449,12 @@ public class IgniteOptimisticTxSuspendResumeTest extends GridCommonAbstractTest
                         }
                     }, TransactionTimeoutException.class);
 
+                    assertTrue(GridTestUtils.waitForCondition(new PA() {
+                        @Override public boolean apply() {
+                            return tx.state() == ROLLED_BACK;
+                        }
+                    }, getTestTimeout()));
+
                     assertEquals(ROLLED_BACK, tx.state());
 
                     tx.close();
@@ -476,6 +489,12 @@ public class IgniteOptimisticTxSuspendResumeTest extends GridCommonAbstractTest
                         }
                     }, TransactionTimeoutException.class);
 
+                    assertTrue(GridTestUtils.waitForCondition(new PA() {
+                        @Override public boolean apply() {
+                            return tx.state() == ROLLED_BACK;
+                        }
+                    }, getTestTimeout()));
+
                     assertEquals(ROLLED_BACK, tx.state());
 
                     tx.close();