org.openengsb.openticket.integrationtest.util.AbstractExamTestHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.openengsb.openticket.integrationtest.util.AbstractExamTestHelper.java

Source

/**
 * Licensed to the Austrian Association for Software Tool Integration (AASTI)
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. The AASTI licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.openengsb.openticket.integrationtest.util;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.ops4j.pax.exam.CoreOptions.felix;
import static org.ops4j.pax.exam.CoreOptions.maven;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.waitForFrameworkStartup;
import static org.ops4j.pax.exam.OptionUtils.combine;
import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures;
import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.workingDirectory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import java.util.UUID;

import junit.framework.Assert;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.karaf.testing.AbstractIntegrationTest;
import org.apache.karaf.testing.Helper;
import org.apache.log4j.LogManager;
import org.apache.log4j.PropertyConfigurator;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.ops4j.pax.exam.Inject;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.Configuration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;
import org.osgi.util.tracker.ServiceTracker;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public abstract class AbstractExamTestHelper extends AbstractIntegrationTest {

    /*
     * to configure loglevel and debug-flag, create a file called itests.local.properties in src/test/resources. This
     * file should only contain simple properties. You can use debug=true and loglevel=INFO in this file.
     */

    private static final long DEFAULT_TIMEOUT = 40000;
    private static final int DEBUG_PORT = 5005;
    protected static final int WEBUI_PORT = 8091;
    protected static final int RMI_REGISTRY_PORT = 1100;
    protected static final int RMI_SERVER_PORT = 44445;

    private boolean isBeforeExecuted = false;

    public enum SetupType {
        BLUEPRINT, SPRING, START_ONLY
    }

    @Inject
    private BundleContext bundleContext;

    protected BundleContext getBundleContext() {
        return bundleContext;
    }

    protected static String getWorkingDirectory() {
        return "target/paxrunner/features/";
    }

    @Before
    public void before() throws Exception {
        if (isBeforeExecuted) {
            // Fix for test runner bug
            return;
        }
        isBeforeExecuted = true;

        List<String> importantBundles = getImportantBundleSymbolicNames();
        for (String bundle : importantBundles) {
            waitForBundle(bundle, SetupType.BLUEPRINT);
        }

        registerConfigPersistence("contextFilePersistenceService", "CONTEXT");
        registerConfigPersistence("workflow-persistence", "WORKFLOW");
        registerConfigPersistence("persistenceService", "CONNECTOR");

        waitForBundle("org.openengsb.ui.admin", SetupType.SPRING);
    }

    public void registerConfigPersistence(String backendId, String configurationId) throws ConfigurationException {
        ManagedServiceFactory factoryService = getOsgiService(ManagedServiceFactory.class,
                "(service.pid=org.openengsb.persistence.config)", 30000);
        Hashtable<String, Object> props = new Hashtable<String, Object>();
        String pid = "org.openengsb.persistence.config." + UUID.randomUUID();
        props.put("backend.id", backendId);
        props.put("configuration.id", configurationId);
        props.put("service.pid", pid);
        factoryService.updated(pid, props);
    }

    public static List<String> getImportantBundleSymbolicNames() {
        List<String> importantBundles = new ArrayList<String>();
        importantBundles.add("org.openengsb.core.api");
        importantBundles.add("org.openengsb.core.common");
        importantBundles.add("org.openengsb.core.service");
        importantBundles.add("org.openengsb.core.persistence");
        importantBundles.add("org.openengsb.core.workflow");
        importantBundles.add("org.openengsb.core.security");
        return importantBundles;
    }

    protected void authenticateAsAdmin() throws InterruptedException {
        authenticate("admin", "password");
    }

    protected void authenticate(String user, String password) throws InterruptedException {
        AuthenticationManager authenticationManager = getOsgiService(AuthenticationManager.class, 20000);
        Authentication authentication = authenticationManager
                .authenticate(new UsernamePasswordAuthenticationToken(user, password));
        assertThat(authentication.isAuthenticated(), is(true));
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }

    protected void waitForBundle(String bundleName, SetupType setupType) throws InterruptedException {
        Bundle[] bundles = bundleContext.getBundles();
        for (Bundle bundle : bundles) {
            if (bundle.getSymbolicName().equals(bundleName)) {
                waitForBundle(bundle, setupType);
                return;
            }
        }
    }

    private void waitForBundle(Bundle bundle, SetupType setupType) throws InterruptedException {
        waitForBundleActivation(bundle);
        if (SetupType.SPRING.equals(setupType)) {
            waitForSpring(bundle);
        } else if (SetupType.BLUEPRINT.equals(setupType)) {
            waitForBlueprint(bundle);
        }
    }

    private void waitForBundleActivation(Bundle bundle) throws InterruptedException {
        int times = 0;
        while (bundle.getState() != Bundle.ACTIVE) {
            if (times > 20) {
                Assert.fail(String.format("Bundle %s still not active", bundle.getSymbolicName()));
            }
            Thread.sleep(3000);
            times++;
        }
    }

    private void waitForSpring(Bundle bundle) throws InterruptedException {
        ServiceTracker tracker = new ServiceTracker(bundle.getBundleContext(),
                "org.springframework.context.ApplicationContext", null);
        tracker.open();
        Object service = tracker.waitForService(60000);
        if (service == null) {
            Assert.fail(String.format("Bundle %s does not start spring service", bundle.getSymbolicName()));
        }
        tracker.close();
    }

    private void waitForBlueprint(Bundle bundle) throws InterruptedException {
        ServiceTracker tracker = new ServiceTracker(bundle.getBundleContext(),
                "org.osgi.service.blueprint.container.BlueprintContainer", null);
        tracker.open();
        Object service = tracker.waitForService(60000);
        if (service == null) {
            Assert.fail(String.format("Bundle %s does not start blueprint service", bundle.getSymbolicName()));
        }
        tracker.close();
    }

    @Override
    protected <T> T getOsgiService(Class<T> type) {
        return getOsgiService(type, null, DEFAULT_TIMEOUT);
    }

    @BeforeClass
    public static void beforeClass() throws IOException {
        try {
            FileUtils.deleteDirectory(new File(getWorkingDirectory()));
        } catch (IOException e) {
            // yes we know about this, but this happens sometimes in windows...
        }
        if (new File("log4j.properties.local").exists()) {
            LogManager.resetConfiguration();
            PropertyConfigurator.configure("log4j.properties.local");
        }
    }

    @AfterClass
    public static void afterClass() throws IOException {
        try {
            FileUtils.deleteDirectory(new File(getWorkingDirectory()));
        } catch (IOException e) {
            // ok, still not funny but lets try if the test passes if the file still exists
        }
    }

    @Configuration
    public static Option[] configuration() throws Exception {
        Option[] baseOptions = Helper.getDefaultOptions();
        /*
         * do not change the values for loglevel or debug here, but refer the comment at the top of the class for
         * further instructions
         */
        String loglevel = "WARN";
        boolean debug = false;
        InputStream paxLocalStream = ClassLoader.getSystemResourceAsStream("itests.local.properties");
        if (paxLocalStream != null) {
            Properties properties = new Properties();
            properties.load(paxLocalStream);
            loglevel = (String) ObjectUtils.defaultIfNull(properties.getProperty("loglevel"), loglevel);
            debug = ObjectUtils.equals(Boolean.TRUE.toString(), properties.getProperty("debug"));
        }

        if (debug) {
            baseOptions = combine(baseOptions, Helper.activateDebugging(Integer.toString(DEBUG_PORT)));
        }
        String targetpath = new File("target").getAbsolutePath();
        FileUtils.deleteDirectory(new File(targetpath, "karaf.data"));
        return combine(baseOptions, Helper.loadKarafStandardFeatures("config", "management"),
                Helper.setLogLevel(loglevel),
                mavenBundle(maven().groupId("org.apache.aries").artifactId("org.apache.aries.util")
                        .versionAsInProject()),
                mavenBundle(maven().groupId("org.apache.aries.proxy").artifactId("org.apache.aries.proxy")
                        .versionAsInProject()),
                mavenBundle(maven().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint")
                        .versionAsInProject()),
                scanFeatures(
                        maven().groupId("org.openengsb.openticket").artifactId("openticket").type("xml")
                                .classifier("features").versionAsInProject(),
                        "openengsb-connector-memoryauditing", "openengsb-ui-admin", "openticket-core"),
                workingDirectory(getWorkingDirectory()),
                vmOption("-Dorg.osgi.framework.system.packages.extra=com.sun.org.apache.xerces.internal.dom,"
                        + "com.sun.org.apache.xerces.internal.jaxp,org.apache.karaf.branding,sun.reflect"),
                vmOption("-Dorg.osgi.service.http.port=" + WEBUI_PORT),
                vmOption("-DrmiRegistryPort=" + RMI_REGISTRY_PORT), vmOption("-DrmiServerPort=" + RMI_SERVER_PORT),
                waitForFrameworkStartup(), vmOption("-Dkaraf.data=" + targetpath + "/karaf.data"),
                vmOption("-Dkaraf.home=" + targetpath + "/karaf.home"),
                vmOption("-Dkaraf.base=" + targetpath + "/karaf.base"),
                mavenBundle(maven().groupId("org.openengsb.wrapped").artifactId("net.sourceforge.htmlunit-all")
                        .versionAsInProject()),
                felix());
    }

}