/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.controller.persistence;
import static java.nio.file.attribute.PosixFilePermission.GROUP_READ;
import static java.nio.file.attribute.PosixFilePermission.OTHERS_READ;
import static java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE;
import static java.nio.file.attribute.PosixFilePermission.OWNER_READ;
import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.AclEntry;
import java.nio.file.attribute.AclEntryFlag;
import java.nio.file.attribute.AclEntryPermission;
import java.nio.file.attribute.AclEntryType;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.UserPrincipal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.jboss.as.controller.PathAddress;
import org.jboss.dmr.ModelNode;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
*/
public class PersistanceResourceTestCase {
File configsDir;
File standardDir;
File externalDir;
File historyDir;
File currentHistoryDir;
File standardFile;
File externalFile;
File lastFile;
File initialFile;
File bootFile;
@Before
public void createDirectoriesAndFiles() throws Exception {
File tgt = new File("target");
if (!tgt.exists()) {
Assert.fail("target/ does not exist");
}
configsDir = createDir(tgt, "persistence-test-configs");
standardDir = createDir(configsDir, "standard");
externalDir = createDir(configsDir, "external");
standardFile = createFile(standardDir, "standard.xml", "std");
externalFile = createFile(externalDir, "standard.xml", "ext");
historyDir = new File(standardDir, "standard_xml_history");
lastFile = new File(historyDir, "standard.last.xml");
bootFile = new File(historyDir, "standard.boot.xml");
initialFile = new File(historyDir, "standard.initial.xml");
currentHistoryDir = new File(historyDir, "current");
}
@After
public void deleteDirectoriesAndFiles() throws Exception {
delete(configsDir);
}
@Test
public void testFileResource() throws Exception {
assertFileContents(standardFile, "std");
TestFileResourcePersister persister = new TestFileResourcePersister(standardFile);
store(persister, "One");
assertFileContents(standardFile, "One");
store(persister, "Two");
assertFileContents(standardFile, "Two");
Assert.assertFalse(historyDir.exists());
}
@Test
public void testDefaultPersistentConfigurationFile() throws Exception {
assertFileContents(standardFile, "std");
Assert.assertFalse(historyDir.exists());
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", null, true);
Assert.assertEquals(standardFile.getCanonicalPath(), configurationFile.getBootFile().getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "std", "std", "std");
store(persister, "One");
checkFiles(null, "One", "std", "std", "One", "std");
store(persister, "Two");
checkFiles(null, "Two", "std", "std", "Two", "std", "One");
store(persister, "Three");
checkFiles(null, "Three", "std", "std", "Three", "std", "One", "Two");
// "Reboot"
configurationFile = new ConfigurationFile(standardDir, "standard.xml", null, true);
Assert.assertEquals(standardFile.getCanonicalPath(), configurationFile.getBootFile().getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "Three", "std", "Three", "Three");
store(persister, "Four");
checkFiles(null, "Four", "std", "Three", "Four", "Three");
}
@Test
public void testOtherPersistentConfigurationFile() throws Exception {
assertFileContents(standardFile, "std");
createFile(standardDir, "test.xml", "non-std");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", "test.xml", true);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(standardDir, "test.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles("test", "non-std", "non-std", "non-std", "non-std");
store(persister, "One");
checkFiles("test", "One", "non-std", "non-std", "One", "non-std");
store(persister, "Two");
checkFiles("test", "Two", "non-std", "non-std", "Two", "non-std", "One");
store(persister, "Three");
checkFiles("test", "Three", "non-std", "non-std", "Three", "non-std", "One", "Two");
// "Reboot"
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "test.xml", true);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(standardFile.getCanonicalFile().getParentFile(), "test.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles("test", "Three", "non-std", "Three", "Three");
store(persister, "Four");
checkFiles("test", "Four", "non-std", "Three", "Four", "Three");
}
@Test
public void testPersistentConfigurationFileFromBackupUsingThePrefix() throws Exception {
//Boot with boot
bootFile.getParentFile().mkdirs();
createFile(historyDir, bootFile.getName(), "boot");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", "boot", true);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(bootFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "boot", "boot", "boot", "boot");
store(persister, "One");
checkFiles(null, "One", "boot", "boot", "One", "boot");
store(persister, "Two");
checkFiles(null, "Two", "boot", "boot", "Two", "boot", "One");
store(persister, "Three");
checkFiles(null, "Three", "boot", "boot", "Three", "boot", "One", "Two");
// "Reboot" with last
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "last", true);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(lastFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "Three", "boot", "Three", "Three");
store(persister, "Four");
checkFiles(null, "Four", "boot", "Three", "Four", "Three");
// "Reboot" with initial
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "initial", true);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(initialFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "boot", "boot", "boot", "boot");
store(persister, "Four");
checkFiles(null, "Four", "boot", "boot", "Four", "boot");
store(persister, "Five");
checkFiles(null, "Five", "boot", "boot", "Five", "boot", "Four");
store(persister, "Six");
checkFiles(null, "Six", "boot", "boot", "Six", "boot", "Four", "Five");
// "Reboot" with v2
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "v2", true);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(currentHistoryDir, "standard.v2.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "Four", "boot", "Four", "Four");
}
@Test
public void testPersistentConfigurationFileFromBackupUsingTheRelativePath() throws Exception {
//Boot with boot
bootFile.getParentFile().mkdirs();
createFile(historyDir, bootFile.getName(), "boot");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/standard.boot.xml", true);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(bootFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "boot", "boot", "boot", "boot");
store(persister, "One");
checkFiles(null, "One", "boot", "boot", "One", "boot");
store(persister, "Two");
checkFiles(null, "Two", "boot", "boot", "Two", "boot", "One");
store(persister, "Three");
checkFiles(null, "Three", "boot", "boot", "Three", "boot", "One", "Two");
// "Reboot" with last
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/standard.last.xml", true);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(lastFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "Three", "boot", "Three", "Three");
store(persister, "Four");
checkFiles(null, "Four", "boot", "Three", "Four", "Three");
// "Reboot" with initial
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/standard.initial.xml", true);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(initialFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "boot", "boot", "boot", "boot");
store(persister, "Four");
checkFiles(null, "Four", "boot", "boot", "Four", "boot");
store(persister, "Five");
checkFiles(null, "Five", "boot", "boot", "Five", "boot", "Four");
store(persister, "Six");
checkFiles(null, "Six", "boot", "boot", "Six", "boot", "Four", "Five");
// "Reboot" with v2
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/current/standard.v2.xml", true);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(currentHistoryDir, "standard.v2.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "Four", "boot", "Four", "Four");
}
@Test(expected = IllegalStateException.class)
public void testPersistentBadRawName() {
new ConfigurationFile(standardDir, "standard.xml", "crap.xml", true);
}
@Test(expected = IllegalStateException.class)
public void testPersistentNameFromOutsideConfigDirectory() throws Exception {
File file = createFile(externalDir, "standard.xml", "test");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", file.getAbsolutePath(), true);
}
@Test
public void testDefaultNonPersistentConfigurationFile() throws Exception {
assertFileContents(standardFile, "std");
Assert.assertFalse(historyDir.exists());
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", null, false);
Assert.assertEquals(standardFile.getCanonicalPath(), configurationFile.getBootFile().getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "std", "std", "std");
store(persister, "One");
checkFiles(null, "std", "std", "std", "One", "std");
store(persister, "Two");
checkFiles(null, "std", "std", "std", "Two", "std", "One");
store(persister, "Three");
checkFiles(null, "std", "std", "std", "Three", "std", "One", "Two");
// "Reboot"
configurationFile = new ConfigurationFile(standardDir, "standard.xml", null, false);
Assert.assertEquals(standardFile.getCanonicalPath(), configurationFile.getBootFile().getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "std", "std", "std");
store(persister, "Four");
checkFiles(null, "std", "std", "std", "Four", "std");
}
@Test
public void testOtherNonPersistentConfigurationFile() throws Exception {
assertFileContents(standardFile, "std");
createFile(standardDir, "test.xml", "non-std");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", "test.xml", false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(standardDir, "test.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles("test", "non-std", "non-std", "non-std", "non-std");
store(persister, "One");
checkFiles("test", "non-std", "non-std", "non-std", "One", "non-std");
store(persister, "Two");
checkFiles("test", "non-std", "non-std", "non-std", "Two", "non-std", "One");
store(persister, "Three");
checkFiles("test", "non-std", "non-std", "non-std", "Three", "non-std", "One", "Two");
// "Reboot"
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "test.xml", false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(standardFile.getCanonicalFile().getParentFile(), "test.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles("test", "non-std", "non-std", "non-std", "non-std");
store(persister, "Four");
checkFiles("test", "non-std", "non-std", "non-std", "Four", "non-std");
}
@Test
public void testNonPersistentConfigurationFileFromBackupUsingThePrefix() throws Exception {
//Boot with boot
bootFile.getParentFile().mkdirs();
createFile(historyDir, bootFile.getName(), "boot");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", "boot", false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(bootFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "boot", "boot");
store(persister, "One");
checkFiles(null, "std", "boot", "boot", "One", "boot");
store(persister, "Two");
checkFiles(null, "std", "boot", "boot", "Two", "boot", "One");
store(persister, "Three");
checkFiles(null, "std", "boot", "boot", "Three", "boot", "One", "Two");
// "Reboot" with last
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "last", false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(lastFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "Three", "Three");
store(persister, "Four");
checkFiles(null, "std", "boot", "Three", "Four", "Three");
// "Reboot" with initial
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "initial", false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(initialFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "boot", "boot");
store(persister, "Four");
checkFiles(null, "std", "boot", "boot", "Four", "boot");
store(persister, "Five");
checkFiles(null, "std", "boot", "boot", "Five", "boot", "Four");
store(persister, "Six");
checkFiles(null, "std", "boot", "boot", "Six", "boot", "Four", "Five");
// "Reboot" with v2
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "v2", false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(currentHistoryDir, "standard.v2.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "Four", "Four");
}
@Test
public void testNonPersistentConfigurationFileFromBackupUsingTheRelativePath() throws Exception {
//Boot with boot
bootFile.getParentFile().mkdirs();
createFile(historyDir, bootFile.getName(), "boot");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/standard.boot.xml", false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(bootFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "boot", "boot");
store(persister, "One");
checkFiles(null, "std", "boot", "boot", "One", "boot");
store(persister, "Two");
checkFiles(null, "std", "boot", "boot", "Two", "boot", "One");
store(persister, "Three");
checkFiles(null, "std", "boot", "boot", "Three", "boot", "One", "Two");
// "Reboot" with last
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/standard.last.xml", false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(lastFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "Three", "Three");
store(persister, "Four");
checkFiles(null, "std", "boot", "Three", "Four", "Three");
// "Reboot" with initial
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/standard.initial.xml", false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(initialFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "boot", "boot");
store(persister, "Four");
checkFiles(null, "std", "boot", "boot", "Four", "boot");
store(persister, "Five");
checkFiles(null, "std", "boot", "boot", "Five", "boot", "Four");
store(persister, "Six");
checkFiles(null, "std", "boot", "boot", "Six", "boot", "Four", "Five");
// "Reboot" with v2
configurationFile = new ConfigurationFile(standardDir, "standard.xml", "standard_xml_history/current/standard.v2.xml", false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(new File(currentHistoryDir, "standard.v2.xml").getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "boot", "Four", "Four");
}
@Test(expected = IllegalStateException.class)
public void testNonPersistentBadRawName() {
new ConfigurationFile(standardDir, "standard.xml", "crap.xml", false);
}
@Test
public void testNonPersistentNameFromOutsideConfigDirectory() throws Exception {
assertFileContents(externalFile, "ext");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", externalFile.getCanonicalPath(), false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(externalFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "ext", "ext", "ext");
assertFileContents(externalFile, "ext");
store(persister, "One");
checkFiles(null, "std", "ext", "ext", "One", "ext");
assertFileContents(externalFile, "ext");
store(persister, "Two");
checkFiles(null, "std", "ext", "ext", "Two", "ext", "One");
assertFileContents(externalFile, "ext");
store(persister, "Three");
checkFiles(null, "std", "ext", "ext", "Three", "ext", "One", "Two");
assertFileContents(externalFile, "ext");
externalFile.delete();
createFile(externalDir, externalFile.getName(), "ext2");
// "Reboot"
configurationFile = new ConfigurationFile(standardDir, "standard.xml", externalFile.getCanonicalPath(), false);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(externalFile.getCanonicalPath(), bootingFile.getCanonicalPath());
persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "ext", "ext2", "ext2");
assertFileContents(externalFile, "ext2");
store(persister, "Four");
checkFiles(null, "std", "ext", "ext2", "Four", "ext2");
assertFileContents(externalFile, "ext2");
}
@Test
public void testPosixFilePermissions() throws Exception {
assertFileContents(standardFile, "std");
if (!Files.getFileStore(standardFile.toPath()).supportsFileAttributeView(PosixFileAttributeView.class)) {
return;
}
PosixFileAttributeView posixStandardFileView = Files.getFileAttributeView(standardFile.toPath(), PosixFileAttributeView.class);
assert posixStandardFileView != null;
Set<PosixFilePermission> readWritePermissions = new HashSet<>(Arrays.asList(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, OTHERS_READ));
//Setting 761 on the file
posixStandardFileView.setPermissions(readWritePermissions);
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", standardFile.getCanonicalPath(), false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(standardFile.getCanonicalPath(), bootingFile.getCanonicalPath());
Path testPermissions = Files.createFile(standardDir.toPath().resolve("TestPermissions.tmp"));
PosixFileAttributeView posixDefaultCreatedFilePermissionView = Files.getFileAttributeView(testPermissions, PosixFileAttributeView.class);
assert posixDefaultCreatedFilePermissionView != null;
Set<PosixFilePermission> defaultPermissions = posixDefaultCreatedFilePermissionView.readAttributes().permissions();
assertThat(defaultPermissions, hasItem(OWNER_READ));
assertThat(defaultPermissions, hasItem(OWNER_WRITE));
assertThat(defaultPermissions, not(hasItem(OWNER_EXECUTE)));
Files.delete(testPermissions);
configurationFile.successfulBoot();
Set<PosixFilePermission> configurationFilePemissions = posixStandardFileView.readAttributes().permissions();
assertThat(configurationFilePemissions, hasItem(OWNER_READ));
assertThat(configurationFilePemissions, hasItem(OWNER_WRITE));
assertThat(configurationFilePemissions, hasItem(OWNER_EXECUTE));
}
@Test
public void testAclFilePermissions() throws Exception {
assertFileContents(standardFile, "std");
if (!Files.getFileStore(standardFile.toPath()).supportsFileAttributeView(AclFileAttributeView.class)) {
return;
}
AclFileAttributeView aclStandardFileView = Files.getFileAttributeView(standardFile.toPath(), AclFileAttributeView.class);
assert aclStandardFileView != null;
List<AclEntry> aclEntries = aclStandardFileView.getAcl();
List<AclEntry> readWritePermissions = new ArrayList<>(aclEntries.size());
final UserPrincipal owner = aclStandardFileView.getOwner();
//Setting execute permissions on the file
for(AclEntry entry : aclEntries) {
if(entry.principal().equals(owner)) {
readWritePermissions.add(createConfigurationAccessACLEntry(entry.principal()));
} else {
readWritePermissions.add(entry);
}
}
aclStandardFileView.setAcl(readWritePermissions);
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", standardFile.getCanonicalPath(), false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(standardFile.getCanonicalPath(), bootingFile.getCanonicalPath());
Path testPermissions = Files.createFile(standardDir.toPath().resolve("TestPermissions.tmp"));
AclFileAttributeView aclDefaultCreatedFilePermissionView = Files.getFileAttributeView(testPermissions, AclFileAttributeView.class);
assert aclDefaultCreatedFilePermissionView != null;
List<AclEntry> defaultPermissions = aclDefaultCreatedFilePermissionView.getAcl();
Set<AclEntryPermission> ownerPermissions = getOwnerPermissions(defaultPermissions, aclDefaultCreatedFilePermissionView.getOwner());
if (!ownerPermissions.isEmpty()) {
assertThat(ownerPermissions.toString(), ownerPermissions, hasItem(AclEntryPermission.WRITE_OWNER));
}
Files.delete(testPermissions);
configurationFile.successfulBoot();
List<AclEntry> configurationFilePermissions = aclStandardFileView.getAcl();
ownerPermissions = getOwnerPermissions(configurationFilePermissions, owner);
assertThat(ownerPermissions.toString(), ownerPermissions, not(hasItem(AclEntryPermission.WRITE_OWNER)));
}
private AclEntry createConfigurationAccessACLEntry(UserPrincipal user) {
AclEntry entry = AclEntry
.newBuilder()
.setType(AclEntryType.ALLOW)
.setPrincipal(user)
.setPermissions(
AclEntryPermission.WRITE_NAMED_ATTRS,
AclEntryPermission.WRITE_DATA,
AclEntryPermission.WRITE_ATTRIBUTES,
AclEntryPermission.READ_ATTRIBUTES,
AclEntryPermission.APPEND_DATA,
AclEntryPermission.READ_DATA,
AclEntryPermission.READ_NAMED_ATTRS,
AclEntryPermission.READ_ACL,
AclEntryPermission.SYNCHRONIZE,
AclEntryPermission.DELETE)
.setFlags(AclEntryFlag.FILE_INHERIT)
.build();
return entry;
}
private Set<AclEntryPermission> getOwnerPermissions(Collection<AclEntry> entries, UserPrincipal owner) {
return entries.stream()
.filter(aclEntry -> aclEntry.principal().equals(owner))
.map(AclEntry::permissions)
.flatMap(Set::stream).collect(Collectors.toSet());
}
@Test
public void testNonPersistentReload() throws Exception {
assertFileContents(standardFile, "std");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", standardFile.getCanonicalPath(), false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(standardFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
checkFiles(null, "std", "std", "std", "std");
store(persister, "One");
checkFiles(null, "std", "std", "std", "One", "std");
configurationFile.resetBootFile(false, null);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(standardFile.getCanonicalPath(), bootingFile.getCanonicalPath());
configurationFile.successfulBoot();
checkFiles(null, "std", "std", "std", "std");
store(persister, "One");
checkFiles(null, "std", "std", "std", "One", "std");
configurationFile.resetBootFile(true, null);
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(addSuffix(standardFile, "last"), bootingFile.getCanonicalPath());
configurationFile.successfulBoot();
checkFiles(null, "std", "std", "One", "One");
}
@Test
public void testReloadPersistentSpecifyingNewConfig() throws Exception {
assertFileContents(standardFile, "std");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", null, true);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(standardFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
store(persister, "One");
checkFiles(null, "One", "std", "std", "One", "std");
//Make sure that a reset to a snapshot loads that file
configurationFile.snapshot();
ConfigurationPersister.SnapshotInfo snapshotInfo = configurationFile.listSnapshots();
Assert.assertEquals(1, snapshotInfo.names().size());
store(persister, "Two");
checkFiles(null, "Two", "std", "std", "Two", "std", "One");
configurationFile.resetBootFile(true, snapshotInfo.names().get(0));
bootingFile = configurationFile.getBootFile();
File snapshotFile = new File(snapshotInfo.getSnapshotDirectory(), snapshotInfo.names().get(0));
Assert.assertEquals(snapshotFile.getCanonicalFile(), bootingFile.getCanonicalFile());
configurationFile.successfulBoot();
checkFiles(null, "One", "std", "One", "One");
//Make sure that a reload to last loads that file
store(persister, "Two");
checkFiles(null, "Two", "std", "One", "Two", "One");
configurationFile.resetBootFile(true, "last");
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(lastFile.getCanonicalFile(), bootingFile.getCanonicalFile());
configurationFile.successfulBoot();
checkFiles(null, "Two", "std", "Two", "Two");
//Make sure that a reload to initial loads that file
store(persister, "Three");
checkFiles(null, "Three", "std", "Two", "Three", "Two");
configurationFile.resetBootFile(true, "initial");
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(initialFile.getCanonicalFile(), bootingFile.getCanonicalFile());
configurationFile.successfulBoot();
checkFiles(null, "std", "std", "std", "std");
}
@Test
public void testReloadNonPersistentSpecifyingNewConfig() throws Exception {
assertFileContents(standardFile, "std");
ConfigurationFile configurationFile = new ConfigurationFile(standardDir, "standard.xml", null, false);
File bootingFile = configurationFile.getBootFile();
Assert.assertEquals(standardFile.getCanonicalPath(), bootingFile.getCanonicalPath());
TestConfigurationFilePersister persister = new TestConfigurationFilePersister(configurationFile);
configurationFile.successfulBoot();
checkDirectoryExists(historyDir);
checkDirectoryExists(currentHistoryDir);
store(persister, "One");
checkFiles(null, "std", "std", "std", "One", "std");
//Make sure that a reset to a snapshot loads that file
configurationFile.snapshot();
ConfigurationPersister.SnapshotInfo snapshotInfo = configurationFile.listSnapshots();
Assert.assertEquals(1, snapshotInfo.names().size());
store(persister, "Two");
checkFiles(null, "std", "std", "std", "Two", "std", "One");
configurationFile.resetBootFile(true, snapshotInfo.names().get(0));
bootingFile = configurationFile.getBootFile();
File snapshotFile = new File(snapshotInfo.getSnapshotDirectory(), snapshotInfo.names().get(0));
Assert.assertEquals(snapshotFile.getCanonicalFile(), bootingFile.getCanonicalFile());
configurationFile.successfulBoot();
checkFiles(null, "std", "std", "One", "One");
//Make sure that a reload to last loads that file
store(persister, "Two");
checkFiles(null, "std", "std", "One", "Two", "One");
configurationFile.resetBootFile(true, "last");
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(lastFile.getCanonicalFile(), bootingFile.getCanonicalFile());
configurationFile.successfulBoot();
checkFiles(null, "std", "std", "Two", "Two");
//Make sure that a reload to initial loads that file
store(persister, "Three");
checkFiles(null, "std", "std", "Two", "Three", "Two");
configurationFile.resetBootFile(true, "initial");
bootingFile = configurationFile.getBootFile();
Assert.assertEquals(initialFile.getCanonicalFile(), bootingFile.getCanonicalFile());
configurationFile.successfulBoot();
checkFiles(null, "std", "std", "std", "std");
}
private String addSuffix(File file, String suffix) throws IOException {
StringBuilder builder = new StringBuilder(file.getParentFile().getCanonicalPath());
System.out.println(builder);
builder.append(File.separatorChar);
builder.append(file.getName().replace('.', '_') + "_history" + File.separatorChar);
builder.append(file.getName().substring(0, file.getName().lastIndexOf(".xml")));
builder.append(".");
builder.append(suffix);
builder.append(".xml");
System.out.println(builder.toString());
return builder.toString();
}
private void checkFiles(String mainFileName, String main, String initial, String boot, String last, String... versions) throws Exception {
File mainFile = this.standardFile;
File bootFile = this.bootFile;
File lastFile = this.lastFile;
File initialFile = this.initialFile;
if (mainFileName != null) {
mainFile = new File(mainFile.getAbsoluteFile().getParent(), mainFileName + ".xml");
bootFile = new File(bootFile.getAbsoluteFile().getParent(), mainFileName + ".boot.xml");
lastFile = new File(bootFile.getAbsoluteFile().getParent(), mainFileName + ".last.xml");
initialFile = new File(bootFile.getAbsoluteFile().getParent(), mainFileName + ".initial.xml");
}
assertFileContents(mainFile, main);
assertFileContents(bootFile, boot);
assertFileContents(lastFile, last);
assertFileContents(initialFile, initial);
checkVersionedHistory(mainFileName == null ? "standard" : mainFileName, versions);
}
private void store(TestConfigurationPersister persister, String s) throws Exception {
persister.store(new ModelNode(s), Collections.<PathAddress>emptySet()).commit();
}
private File createDir(File dir, String name) {
checkDirectoryExists(dir);
File created = new File(dir, name);
created.mkdir();
if (!created.exists()) {
Assert.fail("Could not create " + created);
}
return created;
}
private File createFile(File dir, String name, String contents) throws IOException {
checkDirectoryExists(dir);
File file = new File(dir, name);
if (contents != null) {
Files.write(file.toPath(), contents.getBytes(StandardCharsets.UTF_8));
}
return file;
}
private void checkDirectoryExists(File dir) {
Assert.assertTrue(dir + " does not exist", dir.exists());
Assert.assertTrue(dir + " is not a directory", dir.isDirectory());
}
private void delete(File file) {
if (file.isDirectory()) {
for (String name : file.list()) {
delete(new File(file, name));
}
}
if (!file.delete() && file.exists()) {
Assert.fail("Could not delete " + file);
}
}
private void assertFileContents(File file, String expectedContents) throws Exception {
Assert.assertTrue(file + " does not exist", file.exists());
StringBuilder sb = new StringBuilder();
try (BufferedReader in = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)){
String s = in.readLine();
while (s != null) {
sb.append(s);
s = in.readLine();
}
}
Assert.assertEquals(expectedContents, sb.toString());
}
private void checkVersionedHistory(String name, String... versions) throws Exception {
for (int i = 0; i <= versions.length; i++) {
File file = new File(currentHistoryDir, name + ".v" + (i + 1) + ".xml");
if (i == versions.length) {
Assert.assertFalse(file.exists());
} else {
assertFileContents(file, versions[i]);
}
}
}
private class TestFileResourcePersister extends TestConfigurationPersister {
private final File fileName;
public TestFileResourcePersister(File fileName) {
this.fileName = fileName;
}
@Override
public PersistenceResource create(ModelNode model) throws ConfigurationPersistenceException {
return new FilePersistenceResource(model, fileName, this);
}
}
private class TestConfigurationFilePersister extends TestConfigurationPersister {
private final ConfigurationFile configurationFile;
public TestConfigurationFilePersister(ConfigurationFile configurationFile) {
this.configurationFile = configurationFile;
}
@Override
PersistenceResource create(ModelNode model) throws ConfigurationPersistenceException {
return new ConfigurationFilePersistenceResource(model, configurationFile, this);
}
}
}