http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/spi/encryption/KeystoreEncryptionSpiSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/spi/encryption/KeystoreEncryptionSpiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/encryption/KeystoreEncryptionSpiSelfTest.java new file mode 100644 index 0000000..dd3b164 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/spi/encryption/KeystoreEncryptionSpiSelfTest.java @@ -0,0 +1,123 @@ +/* + * 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.spi.encryption; + +import java.nio.ByteBuffer; +import junit.framework.TestCase; +import org.apache.ignite.IgniteException; +import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey; +import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi; +import org.apache.ignite.testframework.GridTestUtils; +import org.jetbrains.annotations.NotNull; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.ignite.internal.encryption.AbstractEncryptionTest.KEYSTORE_PASSWORD; +import static org.apache.ignite.internal.encryption.AbstractEncryptionTest.KEYSTORE_PATH; + +/** */ +public class KeystoreEncryptionSpiSelfTest extends TestCase { + /** @throws Exception If failed. */ + public void testCantStartWithEmptyParam() throws Exception { + GridTestUtils.assertThrowsWithCause(() -> { + EncryptionSpi encSpi = new KeystoreEncryptionSpi(); + + encSpi.spiStart("default"); + }, IgniteException.class); + } + + /** @throws Exception If failed. */ + public void testCantStartWithoutPassword() throws Exception { + GridTestUtils.assertThrowsWithCause(() -> { + KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi(); + + encSpi.setKeyStorePath("/ignite/is/cool/path/doesnt/exists"); + + encSpi.spiStart("default"); + }, IgniteException.class); + } + + /** @throws Exception If failed. */ + public void testCantStartKeystoreDoesntExists() throws Exception { + GridTestUtils.assertThrowsWithCause(() -> { + KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi(); + + encSpi.setKeyStorePath("/ignite/is/cool/path/doesnt/exists"); + encSpi.setKeyStorePassword(KEYSTORE_PASSWORD.toCharArray()); + + encSpi.spiStart("default"); + }, IgniteException.class); + } + + /** @throws Exception If failed. */ + public void testEncryptDecrypt() throws Exception { + EncryptionSpi encSpi = spi(); + + KeystoreEncryptionKey k = GridTestUtils.getFieldValue(encSpi, "masterKey"); + + assertNotNull(k); + assertNotNull(k.key()); + + byte[] plainText = "Just a test string to encrypt!".getBytes(UTF_8); + byte[] cipherText = new byte[spi().encryptedSize(plainText.length)]; + + encSpi.encrypt(ByteBuffer.wrap(plainText), k, ByteBuffer.wrap(cipherText)); + + assertNotNull(cipherText); + assertEquals(encSpi.encryptedSize(plainText.length), cipherText.length); + + byte[] decryptedText = encSpi.decrypt(cipherText, k); + + assertNotNull(decryptedText); + assertEquals(plainText.length, decryptedText.length); + + assertEquals(new String(plainText, UTF_8), new String(decryptedText, UTF_8)); + } + + /** @throws Exception If failed. */ + public void testKeyEncryptDecrypt() throws Exception { + EncryptionSpi encSpi = spi(); + + KeystoreEncryptionKey k = (KeystoreEncryptionKey)encSpi.create(); + + assertNotNull(k); + assertNotNull(k.key()); + + byte[] encGrpKey = encSpi.encryptKey(k); + + assertNotNull(encGrpKey); + assertTrue(encGrpKey.length > 0); + + KeystoreEncryptionKey k2 = (KeystoreEncryptionKey)encSpi.decryptKey(encGrpKey); + + assertEquals(k.key(), k2.key()); + } + + /** */ + @NotNull private EncryptionSpi spi() throws Exception { + KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi(); + + encSpi.setKeyStorePath(KEYSTORE_PATH); + encSpi.setKeyStorePassword(KEYSTORE_PASSWORD.toCharArray()); + + GridTestUtils.invoke(encSpi, "onBeforeStart"); + + encSpi.spiStart("default"); + + return encSpi; + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java index caa292b..73293ce 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java @@ -1555,51 +1555,58 @@ public final class GridTestUtils { */ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") @Nullable public static <T> T invoke(Object obj, String mtd, Object... params) throws Exception { - // We cannot resolve method by parameter classes due to some of parameters can be null. - // Search correct method among all methods collection. - for (Method m : obj.getClass().getDeclaredMethods()) { - // Filter methods by name. - if (!m.getName().equals(mtd)) - continue; - - if (!areCompatible(params, m.getParameterTypes())) - continue; - - try { - synchronized (m) { - // Backup accessible field state. - boolean accessible = m.isAccessible(); + Class<?> cls = obj.getClass(); + + do { + // We cannot resolve method by parameter classes due to some of parameters can be null. + // Search correct method among all methods collection. + for (Method m : cls.getDeclaredMethods()) { + // Filter methods by name. + if (!m.getName().equals(mtd)) + continue; - try { - if (!accessible) - m.setAccessible(true); + if (!areCompatible(params, m.getParameterTypes())) + continue; - return (T)m.invoke(obj, params); - } - finally { - // Recover accessible field state. - if (!accessible) - m.setAccessible(false); + try { + synchronized (m) { + // Backup accessible field state. + boolean accessible = m.isAccessible(); + + try { + if (!accessible) + m.setAccessible(true); + + return (T)m.invoke(obj, params); + } + finally { + // Recover accessible field state. + if (!accessible) + m.setAccessible(false); + } } } - } - catch (IllegalAccessException e) { - throw new RuntimeException("Failed to access method" + - " [obj=" + obj + ", mtd=" + mtd + ", params=" + Arrays.toString(params) + ']', e); - } - catch (InvocationTargetException e) { - Throwable cause = e.getCause(); + catch (IllegalAccessException e) { + throw new RuntimeException("Failed to access method" + + " [obj=" + obj + ", mtd=" + mtd + ", params=" + Arrays.toString(params) + ']', e); + } + catch (InvocationTargetException e) { + Throwable cause = e.getCause(); - if (cause instanceof Error) - throw (Error) cause; + if (cause instanceof Error) + throw (Error) cause; - if (cause instanceof Exception) - throw (Exception) cause; + if (cause instanceof Exception) + throw (Exception) cause; - throw new RuntimeException("Failed to invoke method)" + - " [obj=" + obj + ", mtd=" + mtd + ", params=" + Arrays.toString(params) + ']', e); + throw new RuntimeException("Failed to invoke method)" + + " [obj=" + obj + ", mtd=" + mtd + ", params=" + Arrays.toString(params) + ']', e); + } } - } + + cls = cls.getSuperclass(); + } while (cls != Object.class); + throw new RuntimeException("Failed to find method" + " [obj=" + obj + ", mtd=" + mtd + ", params=" + Arrays.toString(params) + ']'); http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java index ee0dfa4..13387de 100755 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java @@ -839,8 +839,8 @@ public abstract class GridAbstractTest extends TestCase { * @return Started grid. * @throws Exception If failed. */ - protected Ignite startGrid(String igniteInstanceName) throws Exception { - return startGrid(igniteInstanceName, (GridSpringResourceContext)null); + protected IgniteEx startGrid(String igniteInstanceName) throws Exception { + return (IgniteEx)startGrid(igniteInstanceName, (GridSpringResourceContext)null); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java index 7ce6209..e7876f8 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicWithPersistenceTestSuite.java @@ -22,6 +22,13 @@ import junit.framework.TestSuite; import org.apache.ignite.failure.IoomFailureHandlerTest; import org.apache.ignite.failure.SystemWorkersTerminationTest; import org.apache.ignite.internal.ClusterBaselineNodesMetricsSelfTest; +import org.apache.ignite.internal.encryption.EncryptedCacheBigEntryTest; +import org.apache.ignite.internal.encryption.EncryptedCacheCreateTest; +import org.apache.ignite.internal.encryption.EncryptedCacheDestroyTest; +import org.apache.ignite.internal.encryption.EncryptedCacheGroupCreateTest; +import org.apache.ignite.internal.encryption.EncryptedCacheNodeJoinTest; +import org.apache.ignite.internal.encryption.EncryptedCachePreconfiguredRestartTest; +import org.apache.ignite.internal.encryption.EncryptedCacheRestartTest; import org.apache.ignite.internal.GridNodeMetricsLogPdsSelfTest; import org.apache.ignite.internal.processors.service.ServiceDeploymentOnActivationTest; import org.apache.ignite.internal.processors.service.ServiceDeploymentOutsideBaselineTest; @@ -62,6 +69,14 @@ public class IgniteBasicWithPersistenceTestSuite extends TestSuite { suite.addTestSuite(GridNodeMetricsLogPdsSelfTest.class); + suite.addTestSuite(EncryptedCacheBigEntryTest.class); + suite.addTestSuite(EncryptedCacheCreateTest.class); + suite.addTestSuite(EncryptedCacheDestroyTest.class); + suite.addTestSuite(EncryptedCacheGroupCreateTest.class); + suite.addTestSuite(EncryptedCacheNodeJoinTest.class); + suite.addTestSuite(EncryptedCacheRestartTest.class); + suite.addTestSuite(EncryptedCachePreconfiguredRestartTest.class); + return suite; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java index b8ea850..ab2306e 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java @@ -53,7 +53,6 @@ import org.apache.ignite.internal.processors.port.GridPortProcessorSelfTest; import org.apache.ignite.internal.processors.service.GridServiceClientNodeTest; import org.apache.ignite.internal.processors.service.GridServiceContinuousQueryRedeployTest; import org.apache.ignite.internal.processors.service.GridServiceDeploymentCompoundFutureSelfTest; -import org.apache.ignite.internal.processors.service.GridServiceDeploymentExceptionPropagationTest; import org.apache.ignite.internal.processors.service.GridServicePackagePrivateSelfTest; import org.apache.ignite.internal.processors.service.GridServiceProcessorBatchDeploySelfTest; import org.apache.ignite.internal.processors.service.GridServiceProcessorMultiNodeConfigSelfTest; http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiTestSuite.java index 5de61ae..d5ded38 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiTestSuite.java @@ -20,6 +20,7 @@ package org.apache.ignite.testsuites; import junit.framework.TestSuite; import org.apache.ignite.internal.managers.GridManagerLocalMessageListenerSelfTest; import org.apache.ignite.internal.managers.GridNoopManagerSelfTest; +import org.apache.ignite.spi.encryption.KeystoreEncryptionSpiSelfTest; /** * Grid SPI test suite. @@ -62,6 +63,8 @@ public class IgniteSpiTestSuite extends TestSuite { // Local Message Listener tests. suite.addTestSuite(GridManagerLocalMessageListenerSelfTest.class); + suite.addTestSuite(KeystoreEncryptionSpiSelfTest.class); + return suite; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/resources/other_tde_keystore.jks ---------------------------------------------------------------------- diff --git a/modules/core/src/test/resources/other_tde_keystore.jks b/modules/core/src/test/resources/other_tde_keystore.jks new file mode 100644 index 0000000..6b1f51b Binary files /dev/null and b/modules/core/src/test/resources/other_tde_keystore.jks differ http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/core/src/test/resources/tde.jks ---------------------------------------------------------------------- diff --git a/modules/core/src/test/resources/tde.jks b/modules/core/src/test/resources/tde.jks new file mode 100644 index 0000000..1bf532c Binary files /dev/null and b/modules/core/src/test/resources/tde.jks differ http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java index 8688c4fbd9..5c2865a 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java @@ -72,7 +72,6 @@ import org.apache.ignite.internal.sql.command.SqlIndexColumn; import org.apache.ignite.internal.util.future.GridFinishedFuture; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.plugin.security.SecurityPermission; import org.h2.command.Prepared; import org.h2.command.ddl.AlterTableAlterColumn; @@ -358,7 +357,7 @@ public class DdlStatementsProcessor { ctx.query().dynamicTableCreate(cmd.schemaName(), e, cmd.templateName(), cmd.cacheName(), cmd.cacheGroup(), cmd.dataRegionName(), cmd.affinityKey(), cmd.atomicityMode(), - cmd.writeSynchronizationMode(), cmd.backups(), cmd.ifNotExists()); + cmd.writeSynchronizationMode(), cmd.backups(), cmd.ifNotExists(), cmd.encrypted()); } } else if (stmt0 instanceof GridSqlDropTable) { http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java index de86d6a..0da77bb 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java @@ -84,6 +84,9 @@ public class GridSqlCreateTable extends GridSqlStatement { /** Extra WITH-params. */ private List<String> params; + /** Encrypted flag. */ + private boolean encrypted; + /** * @return Cache name upon which new cache configuration for this table must be based. */ @@ -336,6 +339,20 @@ public class GridSqlCreateTable extends GridSqlStatement { this.params = params; } + /** + * @return Encrypted flag. + */ + public boolean encrypted() { + return encrypted; + } + + /** + * @param encrypted Encrypted flag. + */ + public void encrypted(boolean encrypted) { + this.encrypted = encrypted; + } + /** {@inheritDoc} */ @Override public String getSQL() { return null; http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java index a653e7f..856951f 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java @@ -514,6 +514,9 @@ public class GridSqlQueryParser { public static final String PARAM_DATA_REGION = "DATA_REGION"; /** */ + private static final String PARAM_ENCRYPTED = "ENCRYPTED"; + + /** */ private final IdentityHashMap<Object, Object> h2ObjToGridObj = new IdentityHashMap<>(); /** */ @@ -1610,6 +1613,11 @@ public class GridSqlQueryParser { break; + case PARAM_ENCRYPTED: + res.encrypted(F.isEmpty(val) || Boolean.parseBoolean(val)); + + break; + default: throw new IgniteSQLException("Unsupported parameter: " + name, IgniteQueryErrorCode.PARSING); } http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/encryption/EncryptedSqlTableTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/encryption/EncryptedSqlTableTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/encryption/EncryptedSqlTableTest.java new file mode 100644 index 0000000..4e0e3c3 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/encryption/EncryptedSqlTableTest.java @@ -0,0 +1,69 @@ +/* + * 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.encryption; + +import java.util.List; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.encryption.EncryptedCacheRestartTest; +import org.apache.ignite.internal.util.IgniteUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** */ +public class EncryptedSqlTableTest extends EncryptedCacheRestartTest { + /** {@inheritDoc} */ + @Override protected void createEncryptedCache(IgniteEx grid0, @Nullable IgniteEx grid1, String cacheName, + String cacheGroup, boolean putData) { + + executeSql(grid0, "CREATE TABLE encrypted(ID BIGINT, NAME VARCHAR(10), PRIMARY KEY (ID)) " + + "WITH \"ENCRYPTED=true\""); + executeSql(grid0, "CREATE INDEX enc0 ON encrypted(NAME)"); + + if (putData) { + for (int i=0; i<100; i++) + executeSql(grid0, "INSERT INTO encrypted(ID, NAME) VALUES(?, ?)", i, "" + i); + } + } + + /** {@inheritDoc} */ + @Override protected void checkData(IgniteEx grid0) { + for (int i=0; i<100; i++) { + List<List<?>> res = executeSql(grid0, "SELECT NAME FROM encrypted WHERE ID = ?", i); + + assertEquals(1, res.size()); + assertEquals("" + i, res.get(0).get(0)); + } + } + + /** */ + private List<List<?>> executeSql(IgniteEx grid, String qry, Object...args) { + return grid.context().query().querySqlFields( + new SqlFieldsQuery(qry).setSchema("PUBLIC").setArgs(args), true).getAll(); + } + + /** {@inheritDoc} */ + @NotNull @Override protected String cacheName() { + return "SQL_PUBLIC_ENCRYPTED"; + } + + /** {@inheritDoc} */ + @Override protected String keystorePath() { + return IgniteUtils.resolveIgnitePath("modules/indexing/src/test/resources/tde.jks").getAbsolutePath(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java index 6ed914c..c97d934 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java @@ -34,7 +34,6 @@ import java.util.Random; import java.util.UUID; import java.util.concurrent.Callable; import javax.cache.CacheException; -import org.apache.ignite.Ignite; import org.apache.ignite.IgniteException; import org.apache.ignite.Ignition; import org.apache.ignite.binary.BinaryObject; @@ -44,7 +43,6 @@ import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cache.QueryIndex; import org.apache.ignite.cache.query.SqlFieldsQuery; -import org.apache.ignite.cache.query.annotations.QuerySqlField; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.DataRegionConfiguration; import org.apache.ignite.configuration.DataStorageConfiguration; @@ -881,7 +879,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest { e.setValueType("City"); queryProcessor(client()).dynamicTableCreate("PUBLIC", e, CacheMode.PARTITIONED.name(), null, null, null, - null, CacheAtomicityMode.ATOMIC, null, 10, false); + null, CacheAtomicityMode.ATOMIC, null, 10, false, false); return null; } http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java index 7c8b2f8..7633d2a 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java @@ -104,6 +104,7 @@ import org.apache.ignite.internal.processors.cache.distributed.replicated.Ignite import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQueryEvtsDisabledSelfTest; import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQueryP2PDisabledSelfTest; import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest; +import org.apache.ignite.internal.processors.cache.encryption.EncryptedSqlTableTest; import org.apache.ignite.internal.processors.cache.index.BasicIndexTest; import org.apache.ignite.internal.processors.cache.index.DuplicateKeyValueClassesSelfTest; import org.apache.ignite.internal.processors.cache.index.DynamicIndexClientBasicSelfTest; @@ -472,6 +473,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite { // User operation SQL suite.addTestSuite(SqlParserUserSelfTest.class); suite.addTestSuite(SqlUserCommandSelfTest.class); + suite.addTestSuite(EncryptedSqlTableTest.class); suite.addTestSuite(ThreadLocalObjectPoolSelfTest.class); suite.addTestSuite(H2StatementCacheSelfTest.class); http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/indexing/src/test/resources/tde.jks ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/resources/tde.jks b/modules/indexing/src/test/resources/tde.jks new file mode 100644 index 0000000..1bf532c Binary files /dev/null and b/modules/indexing/src/test/resources/tde.jks differ http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/tde.jks ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/tde.jks b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/tde.jks new file mode 100644 index 0000000..1bf532c Binary files /dev/null and b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/tde.jks differ http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs index 1fd8e72..71d2ba0 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs @@ -64,7 +64,8 @@ namespace Apache.Ignite.Core.Tests.ApiParity "CacheStoreSessionListenerFactories", "PlatformConfiguration", "ExecutorConfiguration", - "CommunicationFailureResolver" + "CommunicationFailureResolver", + "EncryptionSpi" }; /** Properties that are missing on .NET side. */ @@ -97,4 +98,4 @@ namespace Apache.Ignite.Core.Tests.ApiParity KnownMappings); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs index 2861c30..354a511 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs @@ -36,6 +36,7 @@ namespace Apache.Ignite.Core.Tests using Apache.Ignite.Core.Discovery.Tcp; using Apache.Ignite.Core.Discovery.Tcp.Multicast; using Apache.Ignite.Core.Discovery.Tcp.Static; + using Apache.Ignite.Core.Encryption.Keystore; using Apache.Ignite.Core.Events; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.PersistentStore; @@ -81,6 +82,7 @@ namespace Apache.Ignite.Core.Tests CheckDefaultValueAttributes(new IgniteConfiguration()); CheckDefaultValueAttributes(new BinaryConfiguration()); CheckDefaultValueAttributes(new TcpDiscoverySpi()); + CheckDefaultValueAttributes(new KeystoreEncryptionSpi()); CheckDefaultValueAttributes(new CacheConfiguration()); CheckDefaultValueAttributes(new TcpDiscoveryMulticastIpFinder()); CheckDefaultValueAttributes(new TcpCommunicationSpi()); @@ -132,6 +134,14 @@ namespace Apache.Ignite.Core.Tests Assert.AreEqual(disco.ThreadPriority, resDisco.ThreadPriority); Assert.AreEqual(disco.TopologyHistorySize, resDisco.TopologyHistorySize); + var enc = (KeystoreEncryptionSpi) cfg.EncryptionSpi; + var resEnc = (KeystoreEncryptionSpi) resCfg.EncryptionSpi; + + Assert.AreEqual(enc.MasterKeyName, resEnc.MasterKeyName); + Assert.AreEqual(enc.KeySize, resEnc.KeySize); + Assert.AreEqual(enc.KeyStorePath, resEnc.KeyStorePath); + Assert.AreEqual(enc.KeyStorePassword, resEnc.KeyStorePassword); + var ip = (TcpDiscoveryStaticIpFinder) disco.IpFinder; var resIp = (TcpDiscoveryStaticIpFinder) resDisco.IpFinder; @@ -684,6 +694,13 @@ namespace Apache.Ignite.Core.Tests ThreadPriority = 6, TopologyHistorySize = 1234567 }, + EncryptionSpi = new KeystoreEncryptionSpi() + { + KeySize = 192, + KeyStorePassword = "love_sex_god", + KeyStorePath = "tde.jks", + MasterKeyName = KeystoreEncryptionSpi.DefaultMasterKeyName + }, IgniteInstanceName = "gridName1", IgniteHome = IgniteHome.Resolve(null), IncludedEventTypes = EventType.DiscoveryAll, http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index 57357da..f5897c8 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -161,6 +161,10 @@ <Compile Include="Discovery\Tcp\Multicast\Package-Info.cs" /> <Compile Include="Discovery\Tcp\Package-Info.cs" /> <Compile Include="Discovery\Tcp\Static\Package-Info.cs" /> + <Compile Include="Encryption\Package-Info.cs" /> + <Compile Include="Encryption\IEncryptionSpi.cs" /> + <Compile Include="Encryption\Keystore\Package-Info.cs" /> + <Compile Include="Encryption\Keystore\KeystoreEncryptionSpi.cs" /> <Compile Include="Impl\Binary\BinaryArrayEqualityComparer.cs" /> <Compile Include="Impl\Binary\BinaryProcessor.cs" /> <Compile Include="Impl\Binary\BinaryReflectiveSerializerInternal.cs" /> @@ -600,4 +604,4 @@ <Target Name="AfterBuild"> </Target> --> -</Project> \ No newline at end of file +</Project> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs index a8925ad..2e0e1a3 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs @@ -161,6 +161,9 @@ namespace Apache.Ignite.Core.Cache.Configuration /// <summary> Default value for <see cref="QueryParallelism"/>. </summary> public const int DefaultQueryParallelism = 1; + /// <summary> Default value for <see cref="EncryptionEnabled"/>. </summary> + public const bool DefaultEncryptionEnabled = false; + /// <summary> /// Gets or sets the cache name. /// </summary> @@ -214,6 +217,7 @@ namespace Apache.Ignite.Core.Cache.Configuration RebalanceBatchesPrefetchCount = DefaultRebalanceBatchesPrefetchCount; MaxQueryIteratorsCount = DefaultMaxQueryIteratorsCount; QueryParallelism = DefaultQueryParallelism; + EncryptionEnabled = DefaultEncryptionEnabled; } /// <summary> @@ -329,6 +333,7 @@ namespace Apache.Ignite.Core.Cache.Configuration QueryDetailMetricsSize = reader.ReadInt(); QueryParallelism = reader.ReadInt(); SqlSchema = reader.ReadString(); + EncryptionEnabled = reader.ReadBoolean(); QueryEntities = reader.ReadCollectionRaw(r => new QueryEntity(r, srvVer)); @@ -427,6 +432,7 @@ namespace Apache.Ignite.Core.Cache.Configuration writer.WriteInt(QueryDetailMetricsSize); writer.WriteInt(QueryParallelism); writer.WriteString(SqlSchema); + writer.WriteBoolean(EncryptionEnabled); writer.WriteCollectionRaw(QueryEntities, srvVer); @@ -919,5 +925,12 @@ namespace Apache.Ignite.Core.Cache.Configuration /// </summary> [DefaultValue(DefaultQueryParallelism)] public int QueryParallelism { get; set; } + + /// <summary> + /// Gets or sets encryption flag. + /// Default is false. + /// </summary> + [DefaultValue(DefaultEncryptionEnabled)] + public bool EncryptionEnabled { get; set; } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/IEncryptionSpi.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/IEncryptionSpi.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/IEncryptionSpi.cs new file mode 100644 index 0000000..c0ea475 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/IEncryptionSpi.cs @@ -0,0 +1,34 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Encryption +{ + using System.Diagnostics.CodeAnalysis; + using Apache.Ignite.Core.Encryption.Keystore; + + /// <summary> + /// Encryption SPI. + /// <para /> + /// Only predefined implementations are supported: + /// <see cref="KeystoreEncryptionSpi"/> + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")] + public interface IEncryptionSpi + { + // No-op. + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/KeystoreEncryptionSpi.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/KeystoreEncryptionSpi.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/KeystoreEncryptionSpi.cs new file mode 100644 index 0000000..e1866f8 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/KeystoreEncryptionSpi.cs @@ -0,0 +1,84 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Encryption.Keystore +{ + using System.ComponentModel; + using Apache.Ignite.Core.Binary; + + /// <summary> + /// IEncryptionSPI implementation base on JDK provided cipher algorithm implementations. + /// </summary> + public class KeystoreEncryptionSpi : IEncryptionSpi + { + /// <summary> + /// Default master key name. + /// </summary> + public const string DefaultMasterKeyName = "ignite.master.key"; + + /// <summary> + /// Default encryption key size. + /// </summary> + public const int DefaultKeySize = 256; + + /// <summary> + /// Name of master key in key store. + /// </summary> + [DefaultValue(DefaultMasterKeyName)] + public string MasterKeyName { get; set; } + + /// <summary> + /// Size of encryption key. + /// </summary> + [DefaultValue(DefaultKeySize)] + public int KeySize { get; set; } + + /// <summary> + /// Path to key store. + /// </summary> + public string KeyStorePath { get; set; } + + /// <summary> + /// Key store password. + /// </summary> + public string KeyStorePassword { get; set; } + + /// <summary> + /// Empty constructor. + /// </summary> + public KeystoreEncryptionSpi() + { + MasterKeyName = DefaultMasterKeyName; + KeySize = DefaultKeySize; + } + + /// <summary> + /// Initializes a new instance of the <see cref="KeystoreEncryptionSpi"/> class. + /// </summary> + /// <param name="reader">The reader.</param> + public KeystoreEncryptionSpi(IBinaryRawReader reader) + { + MasterKeyName = reader.ReadString(); + KeySize = reader.ReadInt(); + KeyStorePath = reader.ReadString(); + + var keyStorePassword = reader.ReadCharArray(); + + KeyStorePassword = keyStorePassword == null ? null : new string(keyStorePassword); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/Package-Info.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/Package-Info.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/Package-Info.cs new file mode 100644 index 0000000..8df8b34 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Keystore/Package-Info.cs @@ -0,0 +1,26 @@ +/* +* 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. +*/ + +#pragma warning disable 1587 // invalid XML comment + +/// <summary> +/// Encryption API based on standart java keystore. +/// </summary> +namespace Apache.Ignite.Core.Encryption.Keystore +{ + // No-op. +} http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Package-Info.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Package-Info.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Package-Info.cs new file mode 100644 index 0000000..37cafdb --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Encryption/Package-Info.cs @@ -0,0 +1,26 @@ +/* +* 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. +*/ + +#pragma warning disable 1587 // invalid XML comment + +/// <summary> +/// Encryption API. +/// </summary> +namespace Apache.Ignite.Core.Encryption +{ + // No-op. +} http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs index 315b27d..fc6afb6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs @@ -39,6 +39,8 @@ namespace Apache.Ignite.Core using Apache.Ignite.Core.Deployment; using Apache.Ignite.Core.Discovery; using Apache.Ignite.Core.Discovery.Tcp; + using Apache.Ignite.Core.Encryption; + using Apache.Ignite.Core.Encryption.Keystore; using Apache.Ignite.Core.Events; using Apache.Ignite.Core.Failure; using Apache.Ignite.Core.Impl; @@ -373,6 +375,26 @@ namespace Apache.Ignite.Core else writer.WriteBoolean(false); + var enc = EncryptionSpi; + + if (enc != null) + { + writer.WriteBoolean(true); + + var keystoreEnc = enc as KeystoreEncryptionSpi; + + if (keystoreEnc == null) + throw new InvalidOperationException("Unsupported encryption SPI: " + enc.GetType()); + + writer.WriteString(keystoreEnc.MasterKeyName); + writer.WriteInt(keystoreEnc.KeySize); + writer.WriteString(keystoreEnc.KeyStorePath); + writer.WriteCharArray( + keystoreEnc.KeyStorePassword == null ? null : keystoreEnc.KeyStorePassword.ToCharArray()); + } + else + writer.WriteBoolean(false); + // Communication config var comm = CommunicationSpi; @@ -727,6 +749,9 @@ namespace Apache.Ignite.Core // Discovery config DiscoverySpi = r.ReadBoolean() ? new TcpDiscoverySpi(r) : null; + EncryptionSpi = (srvVer.CompareTo(ClientSocket.Ver120) >= 0 && r.ReadBoolean()) ? + new KeystoreEncryptionSpi(r) : null; + // Communication config CommunicationSpi = r.ReadBoolean() ? new TcpCommunicationSpi(r) : null; @@ -1055,6 +1080,12 @@ namespace Apache.Ignite.Core /// Null for default communication. /// </summary> public ICommunicationSpi CommunicationSpi { get; set; } + + /// <summary> + /// Gets or sets the encryption service provider. + /// Null for disabled encryption. + /// </summary> + public IEncryptionSpi EncryptionSpi { get; set; } /// <summary> /// Gets or sets a value indicating whether node should start in client mode. http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd index 4040610..0a55095 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd @@ -862,6 +862,11 @@ <xs:documentation>Desired query parallelism within a single node.</xs:documentation> </xs:annotation> </xs:attribute> + <xs:attribute name="encryptionEnabled" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Flag indicating whether cache encryption enabled.</xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> </xs:sequence> @@ -905,6 +910,38 @@ </xs:sequence> </xs:complexType> </xs:element> + <xs:element name="encryptionSpi" minOccurs="0"> + <xs:annotation> + <xs:documentation>Encryption spi. Null for disabled encryption.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:attribute name="masterKeyName" type="xs:string"> + <xs:annotation> + <xs:documentation>Master key name</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keySize" type="xs:int"> + <xs:annotation> + <xs:documentation>Encryption key size.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keyStorePath" type="xs:string"> + <xs:annotation> + <xs:documentation>Key store path.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keyStorePassword" type="xs:string"> + <xs:annotation> + <xs:documentation>Key store password.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="type" type="xs:string" use="required"> + <xs:annotation> + <xs:documentation>Assembly-qualified type name.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> <xs:element name="discoverySpi" minOccurs="0"> <xs:annotation> <xs:documentation>Discovery service provider. Null for default discovery.</xs:documentation> @@ -999,7 +1036,7 @@ <xs:attribute name="forceServerMode" type="xs:boolean"> <xs:annotation> <xs:documentation> - Whether TcpDiscoverySpi is started in server mode regardless of IgniteConfiguration.ClientMode setting. + Whether TcpDiscoveryspi is started in server mode regardless of IgniteConfiguration.ClientMode setting. </xs:documentation> </xs:annotation> </xs:attribute> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/config/enc/base-enc-cfg.xml ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/config/enc/base-enc-cfg.xml b/modules/spring/src/test/config/enc/base-enc-cfg.xml new file mode 100644 index 0000000..ad17584 --- /dev/null +++ b/modules/spring/src/test/config/enc/base-enc-cfg.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="peerClassLoadingEnabled" value="true"/> + <property name="clientMode" ref="clientMode"/> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="shared" value="false"/> + <property name="addresses"> + <list> + <value>127.0.0.1:47500..47509</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + + <property name="dataStorageConfiguration"> + <bean class="org.apache.ignite.configuration.DataStorageConfiguration"> + <property name="defaultDataRegionConfiguration"> + <bean class="org.apache.ignite.configuration.DataRegionConfiguration"> + <property name="maxSize" value="#{10*1024*1024}"/> + <property name="persistenceEnabled" value="true"/> + </bean> + </property> + <property name="pageSize" value="#{4*1024}"/> + <property name="walMode" value="LOG_ONLY"/> + </bean> + </property> + + <property name="encryptionSpi"> + <bean class="org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi"> + <property name="keyStorePath" value="tde.jks"/> + <property name="keyStorePassword" value="love_sex_god"/> + </bean> + </property> + + <property name="cacheConfiguration"> + <list> + <ref bean="cache.cfg" /> + </list> + </property> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/config/enc/enc-cache-client.xml ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/config/enc/enc-cache-client.xml b/modules/spring/src/test/config/enc/enc-cache-client.xml new file mode 100644 index 0000000..ba4068a --- /dev/null +++ b/modules/spring/src/test/config/enc/enc-cache-client.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="cache.cfg" class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="encrypted-client"/> + <property name="encryptionEnabled" value="true"/> + </bean> + + <bean id="clientMode" class="java.lang.Boolean"> + <constructor-arg value="true"/> + </bean> + + <import resource="base-enc-cfg.xml"/> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/config/enc/enc-cache.xml ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/config/enc/enc-cache.xml b/modules/spring/src/test/config/enc/enc-cache.xml new file mode 100644 index 0000000..88b3ed0 --- /dev/null +++ b/modules/spring/src/test/config/enc/enc-cache.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="cache.cfg" class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="encrypted"/> + <property name="encryptionEnabled" value="true"/> + </bean> + + <bean id="clientMode" class="java.lang.Boolean"> + <constructor-arg value="false"/> + </bean> + + <import resource="base-enc-cfg.xml"/> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/config/enc/enc-group-2.xml ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/config/enc/enc-group-2.xml b/modules/spring/src/test/config/enc/enc-group-2.xml new file mode 100644 index 0000000..60f7031 --- /dev/null +++ b/modules/spring/src/test/config/enc/enc-group-2.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="cache.cfg" class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="encrypted-2"/> + <property name="encryptionEnabled" value="true"/> + <property name="groupName" value="encrypted-group"/> + </bean> + + <bean id="clientMode" class="java.lang.Boolean"> + <constructor-arg value="false"/> + </bean> + + <import resource="base-enc-cfg.xml"/> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/config/enc/enc-group.xml ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/config/enc/enc-group.xml b/modules/spring/src/test/config/enc/enc-group.xml new file mode 100644 index 0000000..33d4659 --- /dev/null +++ b/modules/spring/src/test/config/enc/enc-group.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="cache.cfg" class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="encrypted"/> + <property name="encryptionEnabled" value="true"/> + <property name="groupName" value="encrypted-group"/> + </bean> + + <bean id="clientMode" class="java.lang.Boolean"> + <constructor-arg value="false"/> + </bean> + + <import resource="base-enc-cfg.xml"/> +</beans> + http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/config/enc/not-encrypted-cache-in-group.xml ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/config/enc/not-encrypted-cache-in-group.xml b/modules/spring/src/test/config/enc/not-encrypted-cache-in-group.xml new file mode 100644 index 0000000..a49ddbd --- /dev/null +++ b/modules/spring/src/test/config/enc/not-encrypted-cache-in-group.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="cache.cfg" class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="encrypted-2"/> + <property name="encryptionEnabled" value="false"/> + <property name="groupName" value="encrypted-group"/> + </bean> + + <bean id="clientMode" class="java.lang.Boolean"> + <constructor-arg value="false"/> + </bean> + + <import resource="base-enc-cfg.xml"/> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/config/enc/not-encrypted-cache.xml ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/config/enc/not-encrypted-cache.xml b/modules/spring/src/test/config/enc/not-encrypted-cache.xml new file mode 100644 index 0000000..a9478f6 --- /dev/null +++ b/modules/spring/src/test/config/enc/not-encrypted-cache.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="cache.cfg" class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="encrypted"/> + <property name="encryptionEnabled" value="false"/> + </bean> + + <bean id="clientMode" class="java.lang.Boolean"> + <constructor-arg value="false"/> + </bean> + + <import resource="base-enc-cfg.xml"/> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartClientTest.java ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartClientTest.java b/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartClientTest.java new file mode 100644 index 0000000..fa6de21 --- /dev/null +++ b/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartClientTest.java @@ -0,0 +1,60 @@ +/* + * 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.encryption; + +import org.apache.ignite.IgniteCache; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.IgnitionEx; +import org.apache.ignite.internal.encryption.EncryptedCacheRestartTest; +import org.apache.ignite.internal.util.IgniteUtils; +import org.apache.ignite.internal.util.typedef.T2; + +/** */ +public class SpringEncryptedCacheRestartClientTest extends EncryptedCacheRestartTest { + /** {@inheritDoc} */ + @Override protected void createEncryptedCache(IgniteEx grid0, IgniteEx grid1, String cacheName, String cacheGroup) { + IgniteCache<Long, String> cache = grid0.cache(cacheName()); + + for (long i = 0; i < 100; i++) + cache.put(i, "" + i); + } + + /** {@inheritDoc} */ + @Override protected T2<IgniteEx, IgniteEx> startTestGrids(boolean clnPersDir) throws Exception { + if (clnPersDir) + cleanPersistenceDir(); + + IgniteEx g0 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-cache.xml").getAbsolutePath(), "grid-0"); + + IgniteEx g1 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-cache.xml").getAbsolutePath(), "grid-1"); + + IgniteEx client = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-cache-client.xml").getAbsolutePath(), "client"); + + g1.cluster().active(true); + + awaitPartitionMapExchange(); + + return new T2<>(g1, client); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartTest.java ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartTest.java b/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartTest.java new file mode 100644 index 0000000..6488527 --- /dev/null +++ b/modules/spring/src/test/java/org/apache/ignite/encryption/SpringEncryptedCacheRestartTest.java @@ -0,0 +1,190 @@ +/* + * 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.encryption; + +import java.util.Arrays; +import java.util.Collection; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.IgnitionEx; +import org.apache.ignite.internal.encryption.EncryptedCacheRestartTest; +import org.apache.ignite.internal.processors.cache.IgniteInternalCache; +import org.apache.ignite.internal.util.IgniteUtils; +import org.apache.ignite.internal.util.typedef.T2; +import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionKey; + +import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause; + +/** */ +public class SpringEncryptedCacheRestartTest extends EncryptedCacheRestartTest { + /** {@inheritDoc} */ + @Override protected void createEncryptedCache(IgniteEx grid0, IgniteEx grid1, String cacheName, String cacheGroup) { + IgniteCache<Long, String> cache = grid0.cache(cacheName()); + + for (long i = 0; i < 100; i++) + cache.put(i, "" + i); + } + + /** {@inheritDoc} */ + @Override protected T2<IgniteEx, IgniteEx> startTestGrids(boolean clnPersDir) throws Exception { + if (clnPersDir) + cleanPersistenceDir(); + + IgniteEx g0 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-cache.xml").getAbsolutePath(), "grid-0"); + + IgniteEx g1 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-cache.xml").getAbsolutePath(), "grid-1"); + + g1.cluster().active(true); + + awaitPartitionMapExchange(); + + return new T2<>(g0, g1); + } + + /** @throws Exception If failed. */ + public void testEncryptionKeysEqualsOnThirdNodeJoin() throws Exception { + T2<IgniteEx, IgniteEx> g = startTestGrids(true); + + IgniteEx g2 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-group-2.xml").getAbsolutePath(), "grid-2"); + + Collection<String> cacheNames = Arrays.asList("encrypted", "encrypted-2"); + + for (String cacheName : cacheNames) { + IgniteInternalCache<Object, Object> enc = g.get1().cachex(cacheName); + + assertNotNull(enc); + + int grpId = CU.cacheGroupId(enc.name(), enc.configuration().getGroupName()); + + KeystoreEncryptionKey key0 = (KeystoreEncryptionKey)g.get1().context().encryption().groupKey(grpId); + KeystoreEncryptionKey key1 = (KeystoreEncryptionKey)g.get2().context().encryption().groupKey(grpId); + KeystoreEncryptionKey key2 = (KeystoreEncryptionKey)g2.context().encryption().groupKey(grpId); + + assertNotNull(cacheName, key0); + assertNotNull(cacheName, key1); + assertNotNull(cacheName, key2); + + assertNotNull(cacheName, key0.key()); + assertNotNull(cacheName, key1.key()); + assertNotNull(cacheName, key2.key()); + + assertEquals(cacheName, key0.key(), key1.key()); + assertEquals(cacheName, key1.key(), key2.key()); + } + } + + /** @throws Exception If failed. */ + public void testCreateEncryptedCacheGroup() throws Exception { + IgniteEx g0 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-group.xml").getAbsolutePath(), "grid-0"); + + IgniteEx g1 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-group-2.xml").getAbsolutePath(), "grid-1"); + + g1.cluster().active(true); + + awaitPartitionMapExchange(); + + IgniteInternalCache<Object, Object> encrypted = g0.cachex("encrypted"); + + assertNotNull(encrypted); + + IgniteInternalCache<Object, Object> encrypted2 = g0.cachex("encrypted-2"); + + assertNotNull(encrypted2); + + KeystoreEncryptionKey key = (KeystoreEncryptionKey)g0.context().encryption().groupKey( + CU.cacheGroupId(encrypted.name(), encrypted.configuration().getGroupName())); + + assertNotNull(key); + assertNotNull(key.key()); + + KeystoreEncryptionKey key2 = (KeystoreEncryptionKey)g0.context().encryption().groupKey( + CU.cacheGroupId(encrypted2.name(), encrypted2.configuration().getGroupName())); + + assertNotNull(key2); + assertNotNull(key2.key()); + + assertEquals(key.key(), key2.key()); + } + + /** @throws Exception If failed. */ + public void testCreateNotEncryptedCacheInEncryptedGroupFails() throws Exception { + IgniteEx g0 = (IgniteEx)IgnitionEx.start( + IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/enc-group.xml").getAbsolutePath(), "grid-0"); + + assertThrowsWithCause(() -> { + try { + IgnitionEx.start(IgniteUtils.resolveIgnitePath( + "modules/spring/src/test/config/enc/not-encrypted-cache-in-group.xml").getAbsolutePath(), "grid-1"); + } + catch (IgniteCheckedException e) { + throw new RuntimeException(e); + } + }, IgniteCheckedException.class); + } + + /** @throws Exception If failed. */ + public void testStartWithEncryptedOnDiskPlainInCfg() throws Exception { + doTestDiffCfgAndPersistentFlagVal( + "modules/spring/src/test/config/enc/enc-cache.xml", + "modules/spring/src/test/config/enc/not-encrypted-cache.xml"); + } + + /** @throws Exception If failed. */ + public void testStartWithPlainOnDiskEncryptedInCfg() throws Exception { + doTestDiffCfgAndPersistentFlagVal( + "modules/spring/src/test/config/enc/not-encrypted-cache.xml", + "modules/spring/src/test/config/enc/enc-cache.xml"); + } + + /** */ + private void doTestDiffCfgAndPersistentFlagVal(String cfg1, String cfg2) throws Exception { + cleanPersistenceDir(); + + IgniteEx g = (IgniteEx)IgnitionEx.start(IgniteUtils.resolveIgnitePath(cfg1).getAbsolutePath(), "grid-0"); + + g.cluster().active(true); + + IgniteCache c = g.cache("encrypted"); + + assertNotNull(c); + + stopAllGrids(false); + + assertThrowsWithCause(() -> { + try { + IgnitionEx.start(IgniteUtils.resolveIgnitePath(cfg2).getAbsolutePath(), "grid-0"); + } + catch (IgniteCheckedException e) { + throw new RuntimeException(e); + } + }, IgniteCheckedException.class); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteSpringTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteSpringTestSuite.java b/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteSpringTestSuite.java index 0e590a7..0943d51 100644 --- a/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteSpringTestSuite.java +++ b/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteSpringTestSuite.java @@ -23,6 +23,8 @@ import org.apache.ignite.cache.spring.GridSpringCacheManagerSelfTest; import org.apache.ignite.cache.spring.GridSpringCacheManagerSpringBeanSelfTest; import org.apache.ignite.cache.spring.SpringCacheManagerContextInjectionTest; import org.apache.ignite.cache.spring.SpringCacheTest; +import org.apache.ignite.encryption.SpringEncryptedCacheRestartClientTest; +import org.apache.ignite.encryption.SpringEncryptedCacheRestartTest; import org.apache.ignite.spring.injection.IgniteSpringBeanSpringResourceInjectionTest; import org.apache.ignite.internal.IgniteSpringBeanTest; import org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactorySelfTest; @@ -93,6 +95,10 @@ public class IgniteSpringTestSuite extends TestSuite { suite.addTestSuite(SpringCacheTest.class); + suite.addTestSuite(SpringEncryptedCacheRestartTest.class); + suite.addTestSuite(SpringEncryptedCacheRestartClientTest.class); + + //suite.addTestSuite(GridSpringCacheManagerMultiJvmSelfTest.class); suite.addTestSuite(GridSpringCacheManagerMultiJvmSelfTest.class); suite.addTestSuite(GridCommandLineLoaderTest.class); http://git-wip-us.apache.org/repos/asf/ignite/blob/aabacfa0/modules/spring/src/test/resources/tde.jks ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/resources/tde.jks b/modules/spring/src/test/resources/tde.jks new file mode 100644 index 0000000..1bf532c Binary files /dev/null and b/modules/spring/src/test/resources/tde.jks differ
