package com.constellio.app.modules.es.connectors.smb; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import jcifs.smb.NtlmPasswordAuthentication; import org.assertj.core.groups.Tuple; import org.joda.time.Duration; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.constellio.app.modules.es.connectors.smb.testutils.SmbTestCommand; import com.constellio.app.modules.es.connectors.smb.testutils.SmbTestCommandFactory; import com.constellio.app.modules.es.connectors.smb.testutils.SmbTestCommandFactory.SmbTestCommandType; import com.constellio.app.modules.es.connectors.smb.testutils.SmbTestParams; import com.constellio.app.modules.es.connectors.spi.ConnectorLogger; import com.constellio.app.modules.es.connectors.spi.ConsoleConnectorLogger; import com.constellio.app.modules.es.model.connectors.ConnectorDocument; import com.constellio.app.modules.es.model.connectors.smb.ConnectorSmbDocument; import com.constellio.app.modules.es.model.connectors.smb.ConnectorSmbFolder; import com.constellio.app.modules.es.model.connectors.smb.ConnectorSmbInstance; import com.constellio.app.modules.es.sdk.TestConnectorEventObserver; import com.constellio.app.modules.es.services.ConnectorManager; import com.constellio.app.modules.es.services.ESSchemasRecordsServices; import com.constellio.app.modules.es.services.crawler.ConnectorCrawler; import com.constellio.app.modules.es.services.crawler.DefaultConnectorEventObserver; import com.constellio.data.utils.Factory; import com.constellio.model.services.records.RecordServicesException; import com.constellio.sdk.SDKPasswords; import com.constellio.sdk.tests.ConstellioTest; import com.constellio.sdk.tests.annotations.InDevelopmentTest; import com.constellio.sdk.tests.annotations.SlowTest; @InDevelopmentTest //TODO Activate test public class ConnectorSmbMinimalRealTest extends ConstellioTest { // Minimal share // smb://ip/minimal_share/ // smb://ip/minimal_share/file.txt // smb://ip/minimal_share/folder/ // smb://ip/minimal_share/folder/another_file.txt private String baseUrl = SDKPasswords.testSmbServer(); private String share = SDKPasswords.testSmbShare(); private String fileName = SmbTestParams.FILE_NAME; private String fileContent = SmbTestParams.FILE_CONTENT; private String folderName = SmbTestParams.FOLDER_NAME; private String anotherFileName = SmbTestParams.ANOTHER_FILE_NAME; private String anotherFileContent = SmbTestParams.ANOTHER_FILE_CONTENT; private NtlmPasswordAuthentication auth; private ESSchemasRecordsServices es; private ConnectorManager connectorManager; private ConnectorSmbInstance connectorInstance; private ConnectorLogger logger; private TestConnectorEventObserver eventObserver; private List<String> seeds; private List<String> inclusions; private List<String> exclusions; private SmbTestCommandFactory commandFactory; @Before public void setup() throws IOException { prepareSystem(withZeCollection().withConstellioESModule() .withAllTestUsers()); es = new ESSchemasRecordsServices(zeCollection, getAppLayerFactory()); connectorManager = es.getConnectorManager(); logger = new ConsoleConnectorLogger(); eventObserver = new TestConnectorEventObserver(es, new DefaultConnectorEventObserver(es, logger, "zeTestEventObserver")); auth = new NtlmPasswordAuthentication(SDKPasswords.testSmbDomain(), SDKPasswords.testSmbUsername(), SDKPasswords.testSmbPassword()); commandFactory = new SmbTestCommandFactory(auth); populateMinimalShare(); seeds = Arrays.asList(SDKPasswords.testSmbServer() + share); inclusions = seeds; exclusions = new ArrayList<>(); } @Test @SlowTest public void givenMinimalShareWhenCrawlingThenGetAllDocumentsAndFolders() throws RecordServicesException { createConnector(seeds, inclusions, exclusions); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntilNoMoreRecordsFoundWithinTimeoutForSchemaTypes(Duration.standardMinutes(1), ConnectorSmbDocument.SCHEMA_TYPE, ConnectorSmbFolder.SCHEMA_TYPE); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(2); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(getFetchedFileTuple(), getFetchedAnotherFileTuple()); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(2); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple(), getFetchedFolderTuple()); } @Test @SlowTest public void givenMinimalShareWithNewDocumentWhenCrawlingThenCrawlNewDocument() throws RecordServicesException { String newFileName = "newFile.txt"; String newFileContent = "new File Content"; Tuple newFileTuple = tuple(baseUrl + share + newFileName, newFileContent, true); createConnector(seeds, inclusions, exclusions); SmbTestCommand createFileCommand = commandFactory .get(SmbTestCommandType.CREATE_FILE, baseUrl + share + newFileName, newFileContent); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntil(new NTimesWhileCommandIsExecuted(7, 5, createFileCommand)); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(3); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(getFetchedFileTuple(), getFetchedAnotherFileTuple(), newFileTuple); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(2); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple(), getFetchedFolderTuple()); } @Test @SlowTest public void givenMinimalShareWithNewEmptyFolderWhenCrawlingThenCrawlNewEmptyFolder() throws RecordServicesException { String newFolderName = "newFolder/"; Tuple newFolderTuple = tuple(baseUrl + share + newFolderName, true); createConnector(seeds, inclusions, exclusions); SmbTestCommand createFolderCommand = commandFactory .get(SmbTestCommandType.CREATE_FOLDER, baseUrl + share + newFolderName, ""); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntil(new NTimesWhileCommandIsExecuted(8, 5, createFolderCommand)); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(2); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(getFetchedFileTuple(), getFetchedAnotherFileTuple()); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(3); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple(), getFetchedFolderTuple(), newFolderTuple); } @Test public void givenMinimalShareWithNewFolderWithContentWhenCrawlingThenDetectNewFolderAndContent() throws RecordServicesException { String newFolderName = "newFolderName/"; String newFileName = "newFile.txt"; String newFileContent = "new content"; Tuple newFolderTuple = tuple(baseUrl + share + newFolderName, true); Tuple newFileTuple = tuple(baseUrl + share + newFolderName + newFileName, newFileContent, true); SmbTestCommand createFolderCommand = commandFactory .get(SmbTestCommandType.CREATE_FOLDER, baseUrl + share + newFolderName, ""); SmbTestCommand createFileCommand = commandFactory .get(SmbTestCommandType.CREATE_FILE, baseUrl + share + newFolderName + newFileName, newFileContent); List<SmbTestCommand> commands = Arrays.<SmbTestCommand>asList(createFolderCommand, createFileCommand); createConnector(seeds, inclusions, exclusions); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntil(new NTimesWhileCommandIsExecuted(8, 5, commands)); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(3); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(getFetchedFileTuple(), getFetchedAnotherFileTuple(), newFileTuple); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(3); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple(), getFetchedFolderTuple(), newFolderTuple); } @Test @SlowTest public void givenMinimalShareWithDeletedDocumentWhenCrawlingThenRemoveDocument() throws RecordServicesException { createConnector(seeds, inclusions, exclusions); SmbTestCommand deleteCommand = commandFactory.get(SmbTestCommandType.DELETE, baseUrl + share + fileName, ""); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntil(new NTimesWhileCommandIsExecuted(10, 5, deleteCommand)); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(1); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(getFetchedAnotherFileTuple()); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(2); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple(), getFetchedFolderTuple()); } @Test @SlowTest public void givenMinimalShareWithDeleteEmptyFolderWhenCrawlingThenRemoveFolder() throws RecordServicesException, IOException { String newFolder = "newFolder/"; SmbTestCommand createFolderCommand = commandFactory .get(SmbTestCommandType.CREATE_FOLDER, baseUrl + share + newFolder, ""); createFolderCommand.execute(); createConnector(seeds, inclusions, exclusions); SmbTestCommand deleteCommand = commandFactory.get(SmbTestCommandType.DELETE, baseUrl + share + newFolder, ""); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntil(new NTimesWhileCommandIsExecuted(10, 5, deleteCommand)); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(2); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(getFetchedFileTuple(), getFetchedAnotherFileTuple()); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(2); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple(), getFetchedFolderTuple()); } @Test @SlowTest public void givenMinimalShareDeleteFolderWithContentWhenCrawlingThenRemoveFolderAndContent() throws RecordServicesException { createConnector(seeds, inclusions, exclusions); SmbTestCommand deleteCommand = commandFactory.get(SmbTestCommandType.DELETE, baseUrl + share + folderName, ""); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntil(new NTimesWhileCommandIsExecuted(10, 5, deleteCommand)); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(1); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(getFetchedFileTuple()); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(1); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple()); } @Test @SlowTest public void givenMinimalShareWithModifiedDocumentWhenCrawlingThenUpdateDocument() throws RecordServicesException { String modifiedContent = "Modified Content"; Tuple updatedFileTuple = tuple(baseUrl + share + fileName, modifiedContent, true); createConnector(seeds, inclusions, exclusions); SmbTestCommand updateCommand = commandFactory .get(SmbTestCommandType.UPDATE_FILE, baseUrl + share + fileName, modifiedContent); ConnectorCrawler.runningJobsSequentially(es, eventObserver) .crawlUntil(new NTimesWhileCommandIsExecuted(7, 5, updateCommand)); // Documents List<ConnectorSmbDocument> indexedDocuments = es .searchConnectorSmbDocuments(es.fromConnectorSmbDocumentWhereConnectorIs(connectorInstance)); assertThat(indexedDocuments).hasSize(2); assertThat(indexedDocuments).extracting(getDocumentFields()) .containsOnly(updatedFileTuple, getFetchedAnotherFileTuple()); // Folders List<ConnectorSmbFolder> indexedFolders = es .searchConnectorSmbFolders(es.fromConnectorSmbFolderWhereConnectorIs(connectorInstance)); assertThat(indexedFolders).hasSize(2); assertThat(indexedFolders).extracting(getFolderFields()) .containsOnly(getFetchedShareTuple(), getFetchedFolderTuple()); } @After public void after() { eventObserver.close(); SmbTestCommand cleanShare = commandFactory.get(SmbTestCommandType.CLEAN_SHARE, baseUrl + share, ""); cleanShare.execute(); } private void populateMinimalShare() { SmbTestCommand populateMinimalShare = commandFactory.get(SmbTestCommandType.POPULATE_MINIMAL_SHARE, baseUrl + share, ""); populateMinimalShare.execute(); } private ConnectorSmbInstance createConnector(List<String> seeds, List<String> inclusions, List<String> exclusions) throws RecordServicesException { String connectorCode = "zeConnectorCode"; String connectorTitle = "zeConnectorTitle"; connectorInstance = connectorManager.createConnector(es.newConnectorSmbInstance() .setCode(connectorCode) .setEnabled(true) .setSeeds(seeds) .setUsername(SDKPasswords.testSmbUsername()) .setPassword(SDKPasswords.testSmbPassword()) .setDomain(SDKPasswords.testSmbDomain()) .setInclusions(inclusions) .setExclusions(exclusions) .setTitle(connectorTitle)); es.getRecordServices() .update(connectorInstance.getWrappedRecord()); return connectorInstance; } private String[] getDocumentFields() { return new String[] { ConnectorSmbDocument.URL, ConnectorSmbDocument.PARSED_CONTENT, ConnectorDocument.FETCHED }; } private String[] getFolderFields() { return new String[] { ConnectorSmbFolder.URL, ConnectorDocument.FETCHED }; } private Tuple getFetchedFileTuple() { return tuple(baseUrl + share + fileName, fileContent, true); } private Tuple getFetchedAnotherFileTuple() { return tuple(baseUrl + share + folderName + anotherFileName, anotherFileContent, true); } private Tuple getFetchedShareTuple() { return tuple(baseUrl + share, true); } private Tuple getFetchedFolderTuple() { return tuple(baseUrl + share + folderName, true); } private class NTimesWhileCommandIsExecuted implements Factory<Boolean> { private int currentIteration = 0; private int maxIterations = 0; private int commandIteration = 0; private List<SmbTestCommand> commands; public NTimesWhileCommandIsExecuted(int maxIterations, int commandIteration, SmbTestCommand command) { this.maxIterations = maxIterations; this.commandIteration = commandIteration; this.commands = Arrays.asList(command); } public NTimesWhileCommandIsExecuted(int maxIterations, int commandIteration, List<SmbTestCommand> commands) { this.maxIterations = maxIterations; this.commandIteration = commandIteration; this.commands = commands; } @Override public Boolean get() { currentIteration++; if (currentIteration < maxIterations) { if (currentIteration == commandIteration) { for (SmbTestCommand command : commands) { command.execute(); } } return false; } else { return true; } } } }