com.constellio.sdk.tests.FactoriesTestFeatures.java Source code

Java tutorial

Introduction

Here is the source code for com.constellio.sdk.tests.FactoriesTestFeatures.java

Source

package com.constellio.sdk.tests;

import static com.constellio.data.dao.dto.records.RecordsFlushing.NOW;
import static com.constellio.sdk.tests.TestUtils.asList;
import static org.mockito.Mockito.spy;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.solr.common.params.ModifiableSolrParams;

import com.constellio.app.services.extensions.plugins.ConstellioPluginManager;
import com.constellio.app.services.factories.AppLayerFactory;
import com.constellio.app.services.factories.ConstellioFactories;
import com.constellio.app.ui.i18n.i18n;
import com.constellio.data.conf.ConfigManagerType;
import com.constellio.data.conf.ContentDaoType;
import com.constellio.data.conf.DataLayerConfiguration;
import com.constellio.data.dao.managers.StatefulService;
import com.constellio.data.dao.managers.StatefullServiceDecorator;
import com.constellio.data.dao.services.bigVault.solr.BigVaultException;
import com.constellio.data.dao.services.bigVault.solr.BigVaultException.CouldNotExecuteQuery;
import com.constellio.data.dao.services.bigVault.solr.BigVaultServer;
import com.constellio.data.dao.services.bigVault.solr.BigVaultServerTransaction;
import com.constellio.data.dao.services.factories.DataLayerFactory;
import com.constellio.data.extensions.DataLayerSystemExtensions;
import com.constellio.data.extensions.TransactionLogExtension;
import com.constellio.data.frameworks.extensions.ExtensionBooleanResult;
import com.constellio.data.io.IOServicesFactory;
import com.constellio.data.utils.Factory;
import com.constellio.model.conf.FoldersLocator;
import com.constellio.model.conf.PropertiesModelLayerConfiguration.InMemoryModelLayerConfiguration;
import com.constellio.model.entities.security.global.UserCredential;
import com.constellio.model.services.encrypt.EncryptionServices;
import com.constellio.model.services.factories.ModelLayerFactory;
import com.constellio.sdk.FakeEncryptionServices;

public class FactoriesTestFeatures {

    private boolean fakeEncryptionServices;
    private boolean useSDKPluginFolder;
    //private boolean instanciated = false;
    private boolean backgroundThreadsEnabled = false;
    private boolean checkRollback;
    private List<String> loggingOfRecords = new ArrayList<>();
    private boolean dummyPasswords;

    private File initialState;
    private final FileSystemTestFeatures fileSystemTestFeatures;
    //private ConstellioFactories factoriesInstance;
    private List<Class<?>> spiedClasses = new ArrayList<>();

    private Map<String, TestConstellioFactoriesDecorator> decorators = new HashMap<>();

    //   private Map<String, String> sdkProperties;
    private List<DataLayerConfigurationAlteration> dataLayerConfigurationAlterations = new ArrayList<>();
    private List<ModelLayerConfigurationAlteration> modelLayerConfigurationAlterations = new ArrayList<>();
    private List<AppLayerConfigurationAlteration> appLayerConfigurationAlterations = new ArrayList<>();
    private Map<String, String> configs = new HashMap<>();
    private String systemLanguage;

    public FactoriesTestFeatures(FileSystemTestFeatures fileSystemTestFeatures, Map<String, String> sdkProperties,
            boolean checkRollback) {
        this.fileSystemTestFeatures = fileSystemTestFeatures;
        this.checkRollback = checkRollback;
        //      this.sdkProperties = sdkProperties;
        ConstellioFactories.instanceProvider = new SDKConstellioFactoriesInstanceProvider();
    }

    public void afterTest() {

        if (ConstellioFactories.instanceProvider.isInitialized()) {
            clear();
        }

        ConstellioFactories.clear();

    }

    public void clear() {
        SDKConstellioFactoriesInstanceProvider instanceProvider = (SDKConstellioFactoriesInstanceProvider) ConstellioFactories.instanceProvider;

        for (ConstellioFactories factoriesInstance : instanceProvider.instances.values()) {

            File licenseFile = factoriesInstance.getFoldersLocator().getLicenseFile();
            if (licenseFile.exists()) {
                licenseFile.delete();
            }

            DataLayerConfiguration conf = factoriesInstance.getDataLayerConfiguration();
            for (BigVaultServer server : factoriesInstance.getDataLayerFactory().getSolrServers().getServers()) {
                deleteServerRecords(server);
            }

            if (ContentDaoType.HADOOP == conf.getContentDaoType()) {
                deleteFromHadoop(conf.getContentDaoHadoopUser(), conf.getContentDaoHadoopUrl());

            }

            if (ConfigManagerType.ZOOKEEPER == conf.getSettingsConfigType()) {
                deleteFromZooKeeper(conf.getSettingsZookeeperAddress());
            }

        }
        i18n.clearBundles();
    }

    private void deleteFromZooKeeper(String address) {
        try {
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
            CuratorFramework client = CuratorFrameworkFactory.newClient(address, retryPolicy);
            client.start();
            client.delete().deletingChildrenIfNeeded().forPath("/constellio");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void deleteFromHadoop(String user, String url) {
        System.setProperty("HADOOP_USER_NAME", user);
        Configuration hadoopConfig = new Configuration();

        if (url == null || user == null) {
            throw new RuntimeException("No config");
        }

        hadoopConfig.set("fs.defaultFS", url);
        hadoopConfig.set("hadoop.job.ugi", user);

        try {
            FileSystem hdfs = FileSystem.get(hadoopConfig);
            for (FileStatus file : hdfs.globStatus(new Path("*"))) {
                hdfs.delete(file.getPath(), true);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void deleteServerRecords(BigVaultServer server) {

        BigVaultServer vaultServer = server.clone();
        vaultServer.unregisterAllListeners();
        vaultServer.disableLogger();
        vaultServer.setExtensions(new DataLayerSystemExtensions());

        ModifiableSolrParams allRecordsSolrParams = new ModifiableSolrParams();
        allRecordsSolrParams.set("q", "*:*");

        try {
            vaultServer.addAll(new BigVaultServerTransaction(NOW).addDeletedQuery("*:*"));
        } catch (BigVaultException e) {
            throw new RuntimeException("Cannot deleteLogically by query *:*");
        }
        try {

            if (!vaultServer.query(allRecordsSolrParams).getResults().isEmpty()) {
                throw new RuntimeException("Invalid solr core initial state ");
            }

        } catch (CouldNotExecuteQuery couldNotExecuteQuery) {
            throw new RuntimeException(couldNotExecuteQuery);
        }
    }

    public synchronized ConstellioFactories getConstellioFactories() {
        return getConstellioFactories(SDKConstellioFactoriesInstanceProvider.DEFAULT_NAME);
    }

    public synchronized ConstellioFactories getConstellioFactories(final String name) {
        TestConstellioFactoriesDecorator decorator = decorators.get(name);
        if (decorator == null) {

            StringBuilder setupPropertiesContent = new StringBuilder();
            setupPropertiesContent.append("admin.servicekey=adminkey\n");
            setupPropertiesContent.append("admin.password=password\n");
            File setupProperties = fileSystemTestFeatures.newTempFileWithContent(setupPropertiesContent.toString());

            decorator = new TestConstellioFactoriesDecorator(backgroundThreadsEnabled, true, checkRollback) {

                @Override
                public DataLayerFactory decorateDataLayerFactory(DataLayerFactory dataLayerFactory) {

                    if (!loggingOfRecords.isEmpty()) {
                        dataLayerFactory.getDataLayerLogger().setMonitoredIds(loggingOfRecords);
                    }

                    dataLayerFactory.getExtensions().getSystemWideExtensions().getTransactionLogExtensions()
                            .add(new TransactionLogExtension() {
                                @Override
                                public ExtensionBooleanResult isDocumentFieldLoggedInTransactionLog(String field,
                                        String schema, String collection) {
                                    return ExtensionBooleanResult.FORCE_TRUE;
                                }
                            });

                    if (spiedClasses.isEmpty()) {
                        return dataLayerFactory;
                    } else {
                        return spy(dataLayerFactory);
                    }
                }

                @Override
                public ModelLayerFactory decorateModelServicesFactory(final ModelLayerFactory modelLayerFactory) {

                    if (spiedClasses.isEmpty()) {
                        return modelLayerFactory;
                    } else {
                        return spy(modelLayerFactory);
                    }
                }

                @Override
                public AppLayerFactory decorateAppServicesFactory(final AppLayerFactory appLayerFactory) {

                    if (dummyPasswords) {
                        appLayerFactory.add(new StatefulService() {
                            @Override
                            public void initialize() {
                                try {
                                    ModelLayerFactory modelLayerFactory = appLayerFactory.getModelLayerFactory();
                                    List<UserCredential> users = modelLayerFactory.newUserServices()
                                            .getAllUserCredentials();
                                    StringBuilder passwordFileContent = new StringBuilder();
                                    for (UserCredential user : users) {
                                        passwordFileContent
                                                .append(user.getUsername() + "=W6ph5Mm5Pz8GgiULbPgzG37mj9g\\=\n");
                                    }
                                    File settingsFolder = modelLayerFactory.getDataLayerFactory()
                                            .getDataLayerConfiguration().getSettingsFileSystemBaseFolder();
                                    File authenticationFile = new File(settingsFolder,
                                            "authentification.properties");
                                    try {
                                        FileUtils.write(authenticationFile, passwordFileContent.toString());
                                    } catch (IOException e) {
                                        throw new RuntimeException(e);
                                    }
                                } catch (Exception e) {
                                    //e.printStackTrace();
                                }
                            }

                            @Override
                            public void close() {

                            }
                        });
                    }

                    if (spiedClasses.isEmpty()) {
                        return appLayerFactory;
                    } else {
                        return spy(appLayerFactory);
                    }
                }

                @Override
                public StatefullServiceDecorator getStatefullServiceDecorator() {
                    return new StatefullServiceDecorator() {
                        @Override
                        public <T> T decorate(T service) {

                            if (service != null
                                    && ConstellioPluginManager.class.isAssignableFrom(service.getClass())) {
                                return spy(service);
                            } else {

                                for (Class<?> spiedClass : spiedClasses) {

                                    if (spiedClass.isAssignableFrom(service.getClass())) {
                                        return spy(service);
                                    }
                                }
                            }
                            return service;
                        }
                    };

                }
            };

            if (fakeEncryptionServices) {
                modelLayerConfigurationAlterations.add(new ModelLayerConfigurationAlteration() {
                    @Override
                    public void alter(InMemoryModelLayerConfiguration configuration) {
                        Factory<EncryptionServices> encryptionServicesFactory = new Factory<EncryptionServices>() {
                            @Override
                            public EncryptionServices get() {
                                return new FakeEncryptionServices();
                            }
                        };
                        configuration.setEncryptionServicesFactory(encryptionServicesFactory);
                    }
                });
            }

            File configManagerFolder = fileSystemTestFeatures.newTempFolderWithName("configManagerFolder");
            File contentFolder = fileSystemTestFeatures.newTempFolderWithName("contentFolder");
            File pluginsFolder;
            if (useSDKPluginFolder) {
                pluginsFolder = new SDKFoldersLocator().getPluginsJarsFolder();
            } else {
                pluginsFolder = fileSystemTestFeatures.newTempFolderWithName("plugins");
            }
            File tlogWorkFolder = fileSystemTestFeatures.newTempFolderWithName("tlogWorkFolder");

            decorator.setDataLayerConfigurationAlterations(dataLayerConfigurationAlterations);
            decorator.setModelLayerConfigurationAlterations(modelLayerConfigurationAlterations);
            decorator.setAppLayerConfigurationAlterations(appLayerConfigurationAlterations);
            decorator.setSetupProperties(setupProperties);
            decorator.setImportationFolder(fileSystemTestFeatures.newTempFolderWithName("importationFolder"));
            decorator.setConfigManagerFolder(configManagerFolder);
            decorator.setAppTempFolder(fileSystemTestFeatures.newTempFolderWithName("appTempFolder"));
            decorator.setContentFolder(contentFolder);
            decorator.setPluginsFolder(pluginsFolder)
                    .setPluginsToMoveOnStartupFile(fileSystemTestFeatures.newTempFileWithContent(""));
            decorator.setTransactionLogWorkFolder(tlogWorkFolder);
            decorator.setSystemLanguage(systemLanguage);

            if (initialState != null) {
                if (!ConstellioTest.isCurrentPreservingState()) {
                    File tempFolder = fileSystemTestFeatures.newTempFolder();
                    try {
                        SaveStateFeature.loadStateFrom(initialState, tempFolder, configManagerFolder, contentFolder,
                                pluginsFolder, tlogWorkFolder, dummyPasswords);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            decorators.put(name, decorator);
        }

        File propertyFile = new SDKFoldersLocator().getSDKProperties();

        if (!configs.isEmpty()) {

            File tempPropertyFile = fileSystemTestFeatures.newTempFileInNewTempFolder("temp-sdk.properties");
            StringBuilder basePropertyContent = new StringBuilder();
            try {
                basePropertyContent.append(FileUtils.readFileToString(propertyFile) + "\n");

                for (Map.Entry<String, String> entry : configs.entrySet()) {
                    basePropertyContent.append(entry.getKey() + "=" + entry.getValue() + "\n");
                }

                FileUtils.writeStringToFile(tempPropertyFile, basePropertyContent.toString());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            propertyFile = tempPropertyFile;
        }

        final File finalPropertyFile = propertyFile;
        final TestConstellioFactoriesDecorator finalDecorator = decorator;
        SDKConstellioFactoriesInstanceProvider instanceProvider = (SDKConstellioFactoriesInstanceProvider) ConstellioFactories.instanceProvider;
        return instanceProvider.getInstance(new Factory<ConstellioFactories>() {
            @Override
            public ConstellioFactories get() {
                ConstellioFactories instance = ConstellioFactories.buildFor(finalPropertyFile, finalDecorator,
                        name);
                return instance;
            }
        }, name);
    }

    public void configure(DataLayerConfigurationAlteration dataLayerConfigurationAlteration) {
        dataLayerConfigurationAlterations.add(dataLayerConfigurationAlteration);
    }

    public void configure(ModelLayerConfigurationAlteration modelLayerConfigurationAlteration) {
        modelLayerConfigurationAlterations.add(modelLayerConfigurationAlteration);
    }

    public void configure(AppLayerConfigurationAlteration appLayerConfigurationAlteration) {
        appLayerConfigurationAlterations.add(appLayerConfigurationAlteration);
    }

    public void load() {
        getConstellioFactories();
    }

    public DataLayerFactory newDaosFactory(String name) {
        return getConstellioFactories(name).getDataLayerFactory();
    }

    public IOServicesFactory newIOServicesFactory(String name) {
        return getConstellioFactories(name).getIoServicesFactory();
    }

    public ModelLayerFactory newModelServicesFactory(String name) {
        return getConstellioFactories(name).getModelLayerFactory();
    }

    public AppLayerFactory newAppServicesFactory(String name) {
        return getConstellioFactories(name).getAppLayerFactory();
    }

    public FoldersLocator getFoldersLocator(String name) {
        return getConstellioFactories(name).getFoldersLocator();
    }

    public void withSpiedServices(Class<?>[] classes) {
        spiedClasses.addAll(asList(classes));
    }

    public void givenConstellioProperties(Map<String, String> configs) {
        this.configs.putAll(configs);

    }

    public FactoriesTestFeatures givenSystemInState(File state) {
        this.initialState = state;
        return this;
    }

    public FactoriesTestFeatures withPasswordsReset() {
        this.dummyPasswords = true;
        return this;
    }

    public void setSystemLanguage(String languageCode) {
        this.systemLanguage = languageCode;
    }

    public FactoriesTestFeatures withLoggingOfRecords(String... loggingOfRecordsArray) {
        loggingOfRecords.addAll(asList(loggingOfRecordsArray));
        return this;
    }

    public boolean isInitialized() {
        return ConstellioFactories.instanceProvider.isInitialized();
    }

    public void givenBackgroundThreadsEnabled() {
        backgroundThreadsEnabled = true;
    }

    public FactoriesTestFeatures withoutCheckForRollback() {
        checkRollback = false;
        return this;
    }

    public FactoriesTestFeatures withFakeEncryptionServices() {
        fakeEncryptionServices = true;
        return this;
    }

    public FactoriesTestFeatures withSDKPluginFolder() {
        useSDKPluginFolder = true;
        return this;
    }

    public boolean isCheckRollback() {
        return checkRollback;
    }

}