blob: 072afffa7b9079214c31a149b6081a893e8ed4bf [file] [log] [blame]
/*
* 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.encryption;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterState;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.spi.IgniteSpiException;
import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi;
import org.apache.ignite.testframework.GridTestUtils;
import org.junit.Test;
import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause;
/**
*/
public class EncryptedCacheNodeJoinTest extends AbstractEncryptionTest {
/** */
private static final String GRID_2 = "grid-2";
/** */
private static final String GRID_3 = "grid-3";
/** */
private static final String GRID_4 = "grid-4";
/** */
private static final String GRID_5 = "grid-5";
/** */
private static final String GRID_6 = "grid-6";
/** */
private static final String GRID_7 = "grid-7";
/** */
public static final String CLIENT = "client";
/** */
private boolean configureCache;
/** */
private static final String KEYSTORE_PATH_2 =
IgniteUtils.resolveIgnitePath("modules/core/src/test/resources/other_tde_keystore.jks").getAbsolutePath();
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
cleanPersistenceDir();
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
stopAllGrids();
cleanPersistenceDir();
configureCache = false;
}
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String grid) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(grid);
cfg.setConsistentId(grid);
if (grid.equals(GRID_0) ||
grid.equals(GRID_2) ||
grid.equals(GRID_3) ||
grid.equals(GRID_4) ||
grid.equals(GRID_5) ||
grid.equals(GRID_6) ||
grid.equals(GRID_7)) {
KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi();
encSpi.setKeyStorePath(grid.equals(GRID_2) ? KEYSTORE_PATH_2 : KEYSTORE_PATH);
encSpi.setKeyStorePassword(KEYSTORE_PASSWORD.toCharArray());
cfg.setEncryptionSpi(encSpi);
}
else
cfg.setEncryptionSpi(null);
if (configureCache)
cfg.setCacheConfiguration(cacheConfiguration(grid));
return cfg;
}
/** */
protected CacheConfiguration cacheConfiguration(String gridName) {
CacheConfiguration ccfg = defaultCacheConfiguration();
ccfg.setName(cacheName());
if (gridName.startsWith(CLIENT) ||
gridName.equals(GRID_0) ||
gridName.equals(GRID_6) ||
gridName.equals(GRID_7))
ccfg.setEncryptionEnabled(true);
return ccfg;
}
/** */
@Test
public void testNodeCantJoinWithoutEncryptionSpi() throws Exception {
startGrid(GRID_0);
assertThrowsWithCause(() -> {
try {
startGrid(GRID_1);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}, IgniteCheckedException.class);
}
/** */
@Test
public void testNodeCantJoinWithDifferentKeyStore() throws Exception {
startGrid(GRID_0);
assertThrowsWithCause(() -> {
try {
startGrid(GRID_2);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}, IgniteCheckedException.class);
}
/** */
@Test
public void testNodeCanJoin() throws Exception {
startGrid(GRID_0);
startGrid(GRID_3).cluster().active(true);
}
/** */
@Test
public void testNodeCantJoinWithDifferentCacheKeys() throws Exception {
IgniteEx grid0 = startGrid(GRID_0);
startGrid(GRID_3);
grid0.cluster().active(true);
stopGrid(GRID_3, false);
createEncryptedCache(grid0, null, cacheName(), null, false);
stopGrid(GRID_0, false);
IgniteEx grid3 = startGrid(GRID_3);
grid3.cluster().active(true);
createEncryptedCache(grid3, null, cacheName(), null, false);
assertThrowsWithCause(() -> {
try {
startGrid(GRID_0);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}, IgniteCheckedException.class);
}
/** */
@Test
public void testThirdNodeCanJoin() throws Exception {
IgniteEx grid0 = startGrid(GRID_0);
IgniteEx grid3 = startGrid(GRID_3);
grid3.cluster().active(true);
createEncryptedCache(grid0, grid3, cacheName(), null);
checkEncryptedCaches(grid0, grid3);
IgniteEx grid4 = startGrid(GRID_4);
awaitPartitionMapExchange();
checkEncryptedCaches(grid0, grid4);
}
/** */
@Test
public void testClientNodeJoin() throws Exception {
IgniteEx grid0 = startGrid(GRID_0);
IgniteEx grid3 = startGrid(GRID_3);
grid3.cluster().active(true);
IgniteEx client = startClientGrid(CLIENT);
createEncryptedCache(client, grid0, cacheName(), null);
}
/** */
@Test
public void testClientNodeJoinActiveClusterWithNewStaticCacheConfig() throws Exception {
checkNodeJoinWithStaticCacheConfig(true, true, true);
}
/** */
@Test
public void testClientNodeJoinActiveClusterWithExistingStaticCacheConfig() throws Exception {
checkNodeJoinWithStaticCacheConfig(true, true, false);
}
/** */
@Test
public void testClientNodeJoinInactiveClusterWithNewStaticCacheConfig() throws Exception {
checkNodeJoinWithStaticCacheConfig(true, false, true);
}
/** */
@Test
public void testClientNodeJoinInactiveClusterWithExistingStaticCacheConfig() throws Exception {
checkNodeJoinWithStaticCacheConfig(true, false, false);
}
/** */
@Test
public void testServerNodeJoinActiveClusterWithNewStaticCacheConfig() throws Exception {
checkNodeJoinWithStaticCacheConfig(false, true, true);
}
/** */
@Test
public void testServerNodeJoinInactiveClusterWithNewStaticCacheConfig() throws Exception {
checkNodeJoinWithStaticCacheConfig(false, false, true);
}
/**
* @param client {@code True} to test client node join, {@code False} to test server node join.
* @param activateBeforeJoin {@code True} to activate the server before joining the client node.
* @param newCfg {@code True} to configure cache on the last joined node. {@code False} to configure on all nodes.
*/
private void checkNodeJoinWithStaticCacheConfig(
boolean client,
boolean activateBeforeJoin,
boolean newCfg
) throws Exception {
if (!newCfg)
configureCache = true;
startGrid(GRID_0);
startGrid(GRID_6);
IgniteEx client1 = startClientGrid("client1");
if (newCfg)
configureCache = true;
if (activateBeforeJoin)
grid(GRID_0).cluster().state(ClusterState.ACTIVE);
if (client && newCfg) {
String expErrMsg = "Joining node has encrypted caches which are not presented on the cluster, " +
"encrypted caches configured on client node cannot be started when such node joins " +
"the cluster, these caches can be started manually (dynamically) after node joined" +
"[caches=" + cacheName() + ']';
GridTestUtils.assertThrowsAnyCause(log, () -> startClientGrid(CLIENT), IgniteSpiException.class, expErrMsg);
return;
}
IgniteEx node = client ? startClientGrid(CLIENT) : startGrid(GRID_7);
if (!activateBeforeJoin)
grid(GRID_0).cluster().state(ClusterState.ACTIVE);
awaitPartitionMapExchange();
IgniteCache<Object, Object> cache = node.cache(cacheName());
assertNotNull(cache);
for (long i = 0; i < 100; i++)
cache.put(i, String.valueOf(i));
checkEncryptedCaches(grid(GRID_0), grid(GRID_6));
checkEncryptedCaches(grid(GRID_0), client1);
checkData(client1);
if (client) {
checkEncryptedCaches(grid(GRID_0), grid(CLIENT));
checkData(grid(CLIENT));
}
else
checkEncryptedCaches(grid(GRID_7), grid(GRID_0));
}
/** */
@Test
public void testNodeCantJoinWithSameNameButNotEncCache() throws Exception {
configureCache = true;
IgniteEx grid0 = startGrid(GRID_0);
grid0.cluster().active(true);
assertThrowsWithCause(() -> {
try {
startGrid(GRID_5);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}, IgniteCheckedException.class);
}
/** */
@Test
public void testNodeCantJoinWithSameNameButEncCache() throws Exception {
configureCache = true;
IgniteEx grid0 = startGrid(GRID_5);
grid0.cluster().active(true);
assertThrowsWithCause(() -> {
try {
startGrid(GRID_0);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}, IgniteCheckedException.class);
}
}