package com.constellio.app.services.importExport.systemStateExport;
import static com.constellio.sdk.tests.TestUtils.asList;
import static java.io.File.separator;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.util.List;
import org.assertj.core.api.Condition;
import org.junit.Before;
import org.junit.Test;
import com.constellio.app.modules.rm.RMTestRecords;
import com.constellio.app.modules.rm.services.RMSchemasRecordsServices;
import com.constellio.app.modules.rm.wrappers.Document;
import com.constellio.app.services.extensions.plugins.InvalidJarsTest;
import com.constellio.app.services.importExport.systemStateExport.SystemStateExporterRuntimeException.SystemStateExporterRuntimeException_InvalidRecordId;
import com.constellio.app.services.importExport.systemStateExport.SystemStateExporterRuntimeException.SystemStateExporterRuntimeException_RecordHasNoContent;
import com.constellio.data.conf.HashingEncoding;
import com.constellio.data.io.services.zip.ZipService;
import com.constellio.model.entities.records.Transaction;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.services.contents.ContentManager;
import com.constellio.model.services.contents.ContentVersionDataSummary;
import com.constellio.model.services.records.reindexing.ReindexationMode;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.annotations.SlowTest;
@SlowTest
public class SystemStateExportParamsAcceptTest extends ConstellioTest {
RMTestRecords rmTestRecords = new RMTestRecords(zeCollection);
RMSchemasRecordsServices rm;
String document1Id;
String document1PreviousContent;
String document1CurrentContent;
String document2Id;
String document2PreviousContent;
String document2CurrentContent;
ZipService zipService;
@Before
public void setUp()
throws Exception {
givenHashingEncodingIs(HashingEncoding.BASE64_URL_ENCODED);
givenTransactionLogIsEnabled();
givenDisabledAfterTestValidations();
prepareSystem(
withZeCollection().withAllTestUsers().withConstellioRMModule().withRMTest(rmTestRecords)
.withFoldersAndContainersOfEveryStatus(),
withCollection("anotherCollection").withAllTestUsers().withConstellioRMModule()
);
getModelLayerFactory().newReindexingServices().reindexCollections(ReindexationMode.REWRITE);
User admin = getModelLayerFactory().newUserServices().getUserInCollection("admin", zeCollection);
rm = new RMSchemasRecordsServices(zeCollection, getAppLayerFactory());
ContentManager contentManager = getModelLayerFactory().getContentManager();
ContentVersionDataSummary resource1 = contentManager.upload(getTestResourceInputStream("resource1.docx"));
ContentVersionDataSummary resource2 = contentManager.upload(getTestResourceInputStream("resource2.docx"));
ContentVersionDataSummary resource3 = contentManager.upload(getTestResourceInputStream("resource3.pdf"));
ContentVersionDataSummary resource4 = contentManager.upload(getTestResourceInputStream("resource4.pdf"));
document1PreviousContent = resource1.getHash();
document1CurrentContent = resource2.getHash();
document2PreviousContent = resource3.getHash();
document2CurrentContent = resource4.getHash();
Document document1 = rm.newDocument().setTitle("Document 1").setFolder(rmTestRecords.folder_A04);
document1.setContent(contentManager.createMajor(admin, "file1.docx", resource1).updateContent(admin, resource2, true));
document1Id = document1.getId();
Document document2 = rm.newDocument().setTitle("Document 2").setFolder(rmTestRecords.folder_A04);
document2.setContent(contentManager.createMajor(admin, "file2.pdf", resource3).updateContent(admin, resource4, true));
document2Id = document2.getId();
getModelLayerFactory().newRecordServices().execute(new Transaction().addAll(document1, document2));
zipService = getModelLayerFactory().getIOServicesFactory().newZipService();
getDataLayerFactory().getSecondTransactionLogManager().regroupAndMoveInVault();
}
@Test
public void whenExportingStateWithAllContentThenAllContentVersionsAvailable()
throws Exception {
File unzipFolder = newTempFolder();
File zipFile = new File(newTempFolder(), "file.zip");
SystemStateExportParams params = new SystemStateExportParams();
params.setExportPluginJars(false);
new SystemStateExporter(getAppLayerFactory()).exportSystemToFile(zipFile, params);
zipService.unzip(zipFile, unzipFolder);
assertThat(unzipFolder.list()).containsOnly("settings", "content");
File settingsFolder = new File(unzipFolder, "settings");
assertThat(settingsFolder.list()).contains("collections.xml", "zeCollection", "anotherCollection");
assertThat(new File(settingsFolder, "zeCollection").list()).contains("schemas.xml", "roles.xml", "taxonomies.xml");
File contentFolder = new File(unzipFolder, "content");
assertThat(contentFolder)
.has(transactionLogs())
.has(noTransactionLogBackups())
.has(contents(document1CurrentContent, document1PreviousContent, document2CurrentContent,
document2PreviousContent));
}
@Test
public void whenExportingStateWithNoContentThenNoContentVersionsAvailable()
throws Exception {
File unzipFolder = newTempFolder();
File zipFile = new File(newTempFolder(), "file.zip");
SystemStateExportParams params = new SystemStateExportParams();
params.setExportPluginJars(false);
params.setExportNoContent();
new SystemStateExporter(getAppLayerFactory()).exportSystemToFile(zipFile, params);
zipService.unzip(zipFile, unzipFolder);
assertThat(unzipFolder.list()).containsOnly("settings", "content");
File settingsFolder = new File(unzipFolder, "settings");
assertThat(settingsFolder.list()).contains("collections.xml", "zeCollection", "anotherCollection");
assertThat(new File(settingsFolder, "zeCollection").list()).contains("schemas.xml", "roles.xml", "taxonomies.xml");
File contentFolder = new File(unzipFolder, "content");
assertThat(contentFolder)
.has(transactionLogs())
.has(noTransactionLogBackups())
.has(noContents());
}
@Test
public void whenExportingStateWithPluginsThenAllPluginsExported()
throws Exception {
File unzipFolder = newTempFolder();
File zipFile = new File(newTempFolder(), "file.zip");
SystemStateExportParams params = new SystemStateExportParams();
params.setExportPluginJars(true);
params.setExportNoContent();
File pluginsFolder = getAppLayerFactory().getAppLayerConfiguration().getPluginsFolder();
InvalidJarsTest.loadJarsToPluginsFolder(pluginsFolder);
new SystemStateExporter(getAppLayerFactory()).exportSystemToFile(zipFile, params);
zipService.unzip(zipFile, unzipFolder);
assertThat(unzipFolder.list()).containsOnly("settings", "content", "plugins");
File settingsFolder = new File(unzipFolder, "settings");
assertThat(settingsFolder.list()).contains("collections.xml", "zeCollection", "anotherCollection");
assertThat(new File(settingsFolder, "zeCollection").list()).contains("schemas.xml", "roles.xml", "taxonomies.xml");
File contentFolder = new File(unzipFolder, "content");
assertThat(contentFolder)
.has(transactionLogs())
.has(noTransactionLogBackups())
.has(noContents());
File exportedPluginsFolder = new File(unzipFolder, "plugins");
InvalidJarsTest.assertThatJarsLoadedCorrectly(exportedPluginsFolder);
}
@Test
public void whenExportingStateWithSomeRecordContentThenOnlySpecifiedRecordContent()
throws Exception {
File unzipFolder = newTempFolder();
File zipFile = new File(newTempFolder(), "file.zip");
SystemStateExportParams params = new SystemStateExportParams();
params.setExportPluginJars(false);
params.setOnlyExportContentOfRecords(asList(document1Id));
new SystemStateExporter(getAppLayerFactory())
.exportSystemToFile(zipFile, params);
zipService.unzip(zipFile, unzipFolder);
assertThat(unzipFolder.list()).containsOnly("settings", "content");
File settingsFolder = new File(unzipFolder, "settings");
assertThat(settingsFolder.list()).contains("collections.xml", "zeCollection", "anotherCollection");
assertThat(new File(settingsFolder, "zeCollection").list()).contains("schemas.xml", "roles.xml", "taxonomies.xml");
File contentFolder = new File(unzipFolder, "content");
assertThat(contentFolder)
.has(transactionLogs())
.has(noTransactionLogBackups())
.has(contents(document1CurrentContent, document1PreviousContent));
}
@Test(expected = SystemStateExporterRuntimeException_RecordHasNoContent.class)
public void whenExportingStateWithRecordWithoutContentMetadataThenException()
throws Exception {
File zipFile = new File(newTempFolder(), "file.zip");
SystemStateExportParams params = new SystemStateExportParams();
params.setExportPluginJars(false);
params.setOnlyExportContentOfRecords(asList(document1Id, rmTestRecords.ruleId_1));
new SystemStateExporter(getAppLayerFactory()).exportSystemToFile(zipFile, params);
}
@Test(expected = SystemStateExporterRuntimeException_InvalidRecordId.class)
public void whenExportingStateWithAnInvalidRecordIdThenException()
throws Exception {
File zipFile = new File(newTempFolder(), "file.zip");
SystemStateExportParams params = new SystemStateExportParams();
params.setExportPluginJars(false);
params.setOnlyExportContentOfRecords(asList(document1Id, "anInexistingRecord"));
new SystemStateExporter(getAppLayerFactory()).exportSystemToFile(zipFile, params);
}
private Condition<? super File> noContents() {
return contents();
}
private Condition<? super File> contents(String... hash) {
final List<String> hashes = asList(hash);
return new Condition<File>() {
@Override
public boolean matches(File folder) {
File resource1 = new File(folder, "F/Fs/Fss/Fss7pKBafi8ok5KaOwEpmNdeGCE=".replace("/", separator));
File resource1Parsed = new File(folder, "F/Fs/Fss/Fss7pKBafi8ok5KaOwEpmNdeGCE=__parsed".replace("/", separator));
File resource2 = new File(folder, "T/TI/TIK/TIKwSvHOXHOOtRd1K9t2fm4TQ4I=".replace("/", separator));
File resource2Parsed = new File(folder, "T/TI/TIK/TIKwSvHOXHOOtRd1K9t2fm4TQ4I=__parsed".replace("/", separator));
File resource3 = new File(folder, "T/T-/T-4/T-4zq4cGP_tXkdJp_qz1WVWYhoQ=".replace("/", separator));
File resource3Parsed = new File(folder, "T/T-/T-4/T-4zq4cGP_tXkdJp_qz1WVWYhoQ=__parsed".replace("/", separator));
File resource4 = new File(folder, "K/KN/KN8/KN8RjbrnBgq1EDDV2U71a6_6gd4=".replace("/", separator));
File resource4Parsed = new File(folder, "K/KN/KN8/KN8RjbrnBgq1EDDV2U71a6_6gd4=__parsed".replace("/", separator));
//resource1
if (hashes.contains(document1PreviousContent)) {
assertThat(resource1).exists();
assertThat(resource1Parsed).exists();
} else {
assertThat(resource1).doesNotExist();
assertThat(resource1Parsed).doesNotExist();
}
//resource2
if (hashes.contains(document1CurrentContent)) {
assertThat(resource2).exists();
assertThat(resource2Parsed).exists();
} else {
assertThat(resource2).doesNotExist();
assertThat(resource2Parsed).doesNotExist();
}
//resource3
if (hashes.contains(document2PreviousContent)) {
assertThat(resource3).exists();
assertThat(resource3Parsed).exists();
} else {
assertThat(resource3).doesNotExist();
assertThat(resource3Parsed).doesNotExist();
}
//resource4
if (hashes.contains(document2CurrentContent)) {
assertThat(resource4).exists();
assertThat(resource4Parsed).exists();
} else {
assertThat(resource4).doesNotExist();
assertThat(resource4Parsed).doesNotExist();
}
return true;
}
};
}
private Condition<? super File> transactionLogs() {
return new Condition<File>() {
@Override
public boolean matches(File folder) {
assertThat(folder.list()).contains("tlogs");
assertThat(new File(folder, "tlogs").list()).isNotEmpty();
return true;
}
};
}
private Condition<? super File> noTransactionLogBackups() {
return new Condition<File>() {
@Override
public boolean matches(File folder) {
assertThat(folder.list()).doesNotContain("tlogs_bck");
return true;
}
};
}
}