blob: 63cf8b1cfe5feb9437bb26d9fc5aba656dca31de [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.compatibility.persistence;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.MemoryConfiguration;
import org.apache.ignite.configuration.MemoryPolicyConfiguration;
import org.apache.ignite.configuration.PersistentStoreConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.processors.cache.GridCacheAbstractFullApiSelfTest;
import org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteInClosure;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor.parseSubFolderName;
/**
* Test for new and old style persistent storage folders generation and compatible startup of current ignite version
*/
public class FoldersReuseCompatibilityTest extends IgnitePersistenceCompatibilityAbstractTest {
/** Cache name for test. */
private static final String CACHE_NAME = "dummy";
/** Key to store in previous version of ignite */
private static final String KEY = "StringFromPrevVersion";
/** Value to store in previous version of ignite */
private static final String VAL = "ValueFromPrevVersion";
/** Key to store in previous version of ignite */
private static final String KEY_OBJ = "ObjectFromPrevVersion";
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
final IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
configPersistence(cfg);
return cfg;
}
/**
* Test startup of current ignite version using DB storage folder from previous version of Ignite. Expected to start
* successfully with existing DB
*
* @throws Exception if failed.
*/
public void ignored_testFoldersReuseCompatibility_2_3() throws Exception {
runFoldersReuse("2.3.0");
}
/**
* Test startup of current ignite version using DB storage folder from previous version of Ignite. Expected to start
* successfully with existing DB
*
* @throws Exception if failed.
*/
@Test
public void testFoldersReuseCompatibility_2_2() throws Exception {
runFoldersReuse("2.2.0");
}
/**
* Test startup of current ignite version using DB storage folder from previous version of Ignite. Expected to start
* successfully with existing DB
*
* @throws Exception if failed.
*/
@Test
public void testFoldersReuseCompatibility_2_1() throws Exception {
runFoldersReuse("2.1.0");
}
/**
* Test startup of current ignite version using DB storage folder from previous version of Ignite. Expected to start
* successfully with existing DB
*
* @param ver 3 digit Ignite version to check compatibility with
* @throws Exception if failed.
*/
private void runFoldersReuse(String ver) throws Exception {
final IgniteEx oldVer = startGrid(1, ver, new ConfigurationClosure(), new PostStartupClosure());
stopAllGrids();
IgniteEx ignite = startGrid(0);
ignite.active(true);
ignite.getOrCreateCache("cache2createdForNewGrid").put("Object", "Value");
assertEquals(1, ignite.context().discovery().topologyVersion());
assertPdsDirsDefaultExist(U.maskForFileName(ignite.cluster().node().consistentId().toString()));
assertEquals(VAL, ignite.cache(CACHE_NAME).get(KEY));
final PersistenceBasicCompatibilityTest.TestStringContainerToBePrinted actual = (PersistenceBasicCompatibilityTest.TestStringContainerToBePrinted)ignite.cache(CACHE_NAME).get(KEY_OBJ);
assertEquals(VAL, actual.data);
assertNodeIndexesInFolder();// should not create any new style directories
stopAllGrids();
}
/** Started node test actions closure. */
private static class PostStartupClosure implements IgniteInClosure<Ignite> {
/** {@inheritDoc} */
@Override public void apply(Ignite ignite) {
ignite.active(true);
final IgniteCache<Object, Object> cache = ignite.getOrCreateCache(CACHE_NAME);
cache.put(KEY, VAL);
cache.put("1", "2");
cache.put(1, 2);
cache.put(1L, 2L);
cache.put(PersistenceBasicCompatibilityTest.TestEnum.A, "Enum_As_Key");
cache.put("Enum_As_Value", PersistenceBasicCompatibilityTest.TestEnum.B);
cache.put(PersistenceBasicCompatibilityTest.TestEnum.C, PersistenceBasicCompatibilityTest.TestEnum.C);
cache.put("Serializable", new PersistenceBasicCompatibilityTest.TestSerializable(42));
cache.put(new PersistenceBasicCompatibilityTest.TestSerializable(42), "Serializable_As_Key");
cache.put("Externalizable", new PersistenceBasicCompatibilityTest.TestExternalizable(42));
cache.put(new PersistenceBasicCompatibilityTest.TestExternalizable(42), "Externalizable_As_Key");
cache.put(KEY_OBJ, new PersistenceBasicCompatibilityTest.TestStringContainerToBePrinted(VAL));
}
}
/** Setup compatible node closure. */
private static class ConfigurationClosure implements IgniteInClosure<IgniteConfiguration> {
/** {@inheritDoc} */
@Override public void apply(IgniteConfiguration cfg) {
cfg.setLocalHost("127.0.0.1");
TcpDiscoverySpi disco = new TcpDiscoverySpi();
disco.setIpFinder(GridCacheAbstractFullApiSelfTest.LOCAL_IP_FINDER);
cfg.setDiscoverySpi(disco);
configPersistence(cfg);
}
}
/**
* Setup persistence for compatible and current version node.
*
* @param cfg ignite config to setup.
*/
private static void configPersistence(IgniteConfiguration cfg) {
final PersistentStoreConfiguration psCfg = new PersistentStoreConfiguration();
cfg.setPersistentStoreConfiguration(psCfg);
final MemoryConfiguration memCfg = new MemoryConfiguration();
final MemoryPolicyConfiguration memPolCfg = new MemoryPolicyConfiguration();
memPolCfg.setMaxSize(32L * 1024 * 1024); // we don't need much memory for this test
memCfg.setMemoryPolicies(memPolCfg);
cfg.setMemoryConfiguration(memCfg);
}
/**
* @param indexes expected new style node indexes in folders
* @throws IgniteCheckedException if failed
*/
private void assertNodeIndexesInFolder(Integer... indexes) throws IgniteCheckedException {
assertEquals(new TreeSet<>(Arrays.asList(indexes)), getAllNodeIndexesInFolder());
}
/**
* @return set of all indexes of nodes found in work folder
* @throws IgniteCheckedException if failed.
*/
@NotNull private Set<Integer> getAllNodeIndexesInFolder() throws IgniteCheckedException {
final File curFolder = new File(U.defaultWorkDirectory(), PdsConsistentIdProcessor.DB_DEFAULT_FOLDER);
final Set<Integer> indexes = new TreeSet<>();
final File[] files = curFolder.listFiles(PdsConsistentIdProcessor.DB_SUBFOLDERS_NEW_STYLE_FILTER);
for (File file : files) {
final PdsConsistentIdProcessor.FolderCandidate uid
= parseSubFolderName(file, log);
if (uid != null)
indexes.add(uid.nodeIndex());
}
return indexes;
}
/**
* Checks existence of all storage-related directories
*
* @param subDirName sub directories name expected
* @throws IgniteCheckedException if IO error occur
*/
private void assertPdsDirsDefaultExist(String subDirName) throws IgniteCheckedException {
assertDirectoryExist(DataStorageConfiguration.DFLT_BINARY_METADATA_PATH, subDirName);
assertDirectoryExist(PersistentStoreConfiguration.DFLT_WAL_STORE_PATH, subDirName);
assertDirectoryExist(PersistentStoreConfiguration.DFLT_WAL_ARCHIVE_PATH, subDirName);
assertDirectoryExist(PdsConsistentIdProcessor.DB_DEFAULT_FOLDER, subDirName);
}
/**
* Checks one folder existence
*
* @param subFolderNames subfolders array to touch
* @throws IgniteCheckedException if IO error occur
*/
private void assertDirectoryExist(String... subFolderNames) throws IgniteCheckedException {
File curFolder = new File(U.defaultWorkDirectory());
for (String name : subFolderNames) {
curFolder = new File(curFolder, name);
}
final String path;
try {
path = curFolder.getCanonicalPath();
}
catch (IOException e) {
throw new IgniteCheckedException("Failed to convert path: [" + curFolder.getAbsolutePath() + "]", e);
}
assertTrue("Directory " + Arrays.asList(subFolderNames).toString()
+ " is expected to exist [" + path + "]", curFolder.exists() && curFolder.isDirectory());
}
}