/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Damien Metzler (Leroy Merlin, http://www.leroymerlin.fr/) */ package org.nuxeo.ecm.core.test; import static org.junit.Assert.assertNotNull; import java.net.URL; import java.security.Principal; import java.util.ArrayList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.CoreInstance; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.impl.UserPrincipal; import org.nuxeo.ecm.core.api.security.SecurityConstants; import org.nuxeo.ecm.core.repository.RepositoryFactory; import org.nuxeo.ecm.core.storage.sql.DatabaseHelper; import org.nuxeo.ecm.core.test.annotations.BackendType; import org.nuxeo.ecm.core.test.annotations.Granularity; import org.nuxeo.ecm.core.test.annotations.RepositoryConfig; import org.nuxeo.ecm.core.test.annotations.RepositoryInit; import org.nuxeo.osgi.OSGiAdapter; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.datasource.ConnectionHelper; import org.nuxeo.runtime.model.persistence.Contribution; import org.nuxeo.runtime.model.persistence.fs.ContributionLocation; import org.nuxeo.runtime.test.runner.Defaults; import org.nuxeo.runtime.test.runner.FeaturesRunner; import org.nuxeo.runtime.test.runner.RuntimeFeature; import org.nuxeo.runtime.test.runner.RuntimeHarness; import org.nuxeo.runtime.test.runner.ServiceProvider; import org.osgi.framework.Bundle; import com.google.inject.Scope; /** * Repository configuration that can be set using {@link RepositoryConfig} annotations. * <p> * If you are modifying fields in this class do not forget to update the * {@link RepositorySettings#importSettings(RepositorySettings) method. * * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> */ public class RepositorySettings extends ServiceProvider<CoreSession> { private static final Log log = LogFactory.getLog(RepositorySettings.class); protected FeaturesRunner runner; protected BackendType type; protected String repositoryName; protected String databaseName; protected String username; protected String singleDatasource; protected RepositoryInit repoInitializer; protected Granularity granularity; protected Class<? extends RepositoryFactory> repositoryFactoryClass; protected CoreSession session; /** * Do not use this ctor - it will be used by {@link MultiNuxeoCoreRunner}. */ protected RepositorySettings() { super(CoreSession.class); importAnnotations(Defaults.of(RepositoryConfig.class)); } protected RepositorySettings(RepositoryConfig config) { super(CoreSession.class); importAnnotations(config); } protected RepositorySettings(FeaturesRunner runner, RepositoryConfig config) { super(CoreSession.class); this.runner = runner; importAnnotations(config); } public RepositorySettings(FeaturesRunner runner) { super(CoreSession.class); this.runner = runner; RepositoryConfig conf = runner.getConfig(RepositoryConfig.class); if (conf == null) { conf = Defaults.of(RepositoryConfig.class); } importAnnotations(conf); } public void importAnnotations(RepositoryConfig repo) { type = repo.type(); singleDatasource = repo.singleDatasource(); repositoryName = repo.repositoryName(); databaseName = repo.databaseName(); username = repo.user(); granularity = repo.cleanup(); repositoryFactoryClass = repo.repositoryFactoryClass(); repoInitializer = newInstance(repo.init()); } protected <T> T newInstance(Class<? extends T> clazz) { try { return clazz.newInstance(); } catch (Exception e) { throw new RuntimeException("Cannot instantiate " + clazz.getSimpleName(), e); } } public void importSettings(RepositorySettings settings) { shutdown(); // override only the user name and the type. // overriding initializer and granularity may broke tests that are // using specific initializers RepositoryConfig defaultConfig = Defaults.of(RepositoryConfig.class); if (defaultConfig.type() != settings.type) { type = settings.type; } username = settings.username; repositoryName = settings.repositoryName; databaseName = settings.databaseName; singleDatasource = settings.singleDatasource; } public BackendType getBackendType() { return type; } public void setBackendType(BackendType type) { this.type = type; } public String getName() { return repositoryName; } public void setName(String name) { repositoryName = name; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public RepositoryInit getInitializer() { return repoInitializer; } public void setInitializer(RepositoryInit initializer) { repoInitializer = initializer; } public Granularity getGranularity() { return granularity; } public void setGranularity(Granularity granularity) { this.granularity = granularity; } public void initialize() { DatabaseHelper dbHelper = DatabaseHelper.DATABASE; try { RuntimeHarness harness = runner.getFeature(RuntimeFeature.class).getHarness(); log.info("Deploying a VCS repo implementation"); // type is ignored, the config inferred by DatabaseHelper from // system properties will be used dbHelper.setRepositoryName(repositoryName); if (!singleDatasource.isEmpty()) { Framework.getProperties().setProperty(ConnectionHelper.SINGLE_DS, singleDatasource); } dbHelper.setUp(repositoryFactoryClass); OSGiAdapter osgi = harness.getOSGiAdapter(); Bundle bundle = osgi.getRegistry().getBundle( "org.nuxeo.ecm.core.storage.sql.test"); String contribPath = dbHelper.getDeploymentContrib(); URL contribURL = bundle.getEntry(contribPath); assertNotNull("deployment contrib " + contribPath + " not found", contribURL); Contribution contrib = new ContributionLocation(repositoryName, contribURL); harness.getContext().deploy(contrib); } catch (Exception e) { log.error(e.toString(), e); } } public void shutdown() { if (session != null) { releaseSession(); } } public CoreSession createSession() { assert session == null; try { session = openSessionAs(getUsername(), true, false); } catch (Exception cause) { throw new AssertionError("Cannot create session", cause); } return session; } /** * @since 5.6 */ public void releaseSession() { assert session != null; session.close(); session = null; } public CoreSession getSession() { return session; } /** * Opens a {@link CoreSession} for the currently logged-in user. * <p> * The session must be closed using {@link CoreSession#close}. * * @return the session * @since 5.9.3 */ public CoreSession openSession() throws ClientException { return CoreInstance.openCoreSession(repositoryName); } /** * Opens a {@link CoreSession} for the given user. * <p> * The session must be closed using {@link CoreSession#close}. * * @param username the user name * @return the session */ public CoreSession openSessionAs(String username) throws ClientException { return CoreInstance.openCoreSession(repositoryName, username); } /** * Opens a {@link CoreSession} for the given principal. * <p> * The session must be closed using {@link CoreSession#close}. * * @param principal the principal * @return the session * @since 5.9.3 */ public CoreSession openSessionAs(Principal principal) throws ClientException { return CoreInstance.openCoreSession(repositoryName, principal); } public CoreSession openSessionAsAdminUser(String username) throws ClientException { return openSessionAs(username, true, false); } public CoreSession openSessionAsAnonymousUser(String username) throws ClientException { return openSessionAs(username, false, true); } public CoreSession openSessionAsSystemUser() throws ClientException { return openSessionAs(SecurityConstants.SYSTEM_USERNAME, true, false); } public CoreSession openSessionAs(String username, boolean isAdmin, boolean isAnonymous) throws ClientException { UserPrincipal principal = new UserPrincipal(username, new ArrayList<String>(), isAnonymous, isAdmin); return CoreInstance.openCoreSession(repositoryName, principal); } @Override public CoreSession get() { return getSession(); } @Override public Scope getScope() { return CoreScope.INSTANCE; } }