Package com.asakusafw.testdriver.windgate.emulation

Source Code of com.asakusafw.testdriver.windgate.emulation.AbstractWindGateCommandEmulator

/**
* Copyright 2011-2014 Asakusa Framework Team.
*
* Licensed 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 com.asakusafw.testdriver.windgate.emulation;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import com.asakusafw.testdriver.TestDriverContext;
import com.asakusafw.testdriver.TestExecutionPlan;
import com.asakusafw.testdriver.hadoop.ConfigurationFactory;
import com.asakusafw.testdriver.inprocess.CommandEmulator;
import com.asakusafw.testdriver.inprocess.EmulatorUtils;
import com.asakusafw.windgate.bootstrap.CommandLineUtil;
import com.asakusafw.windgate.core.GateProfile;
import com.asakusafw.windgate.core.ParameterList;
import com.asakusafw.windgate.core.ProfileContext;

/**
* An abstract implementation of WindGate command emulators.
* @since 0.6.0
*/
public abstract class AbstractWindGateCommandEmulator extends CommandEmulator {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractWindGateCommandEmulator.class);

    static final String MODULE_NAME_PREFIX = "windgate.";

    static final String PATH_WINDGATE = "windgate";

    private static final String PATH_CONF = PATH_WINDGATE + "/conf";

    private static final String PATH_PLUGIN = PATH_WINDGATE + "/plugin";

    private static final String PATTERN_PROFILE = PATH_WINDGATE + "/profile/{0}.properties";

    private static final int ARG_PROFILE = 1;

    @Override
    public final void execute(
            TestDriverContext context,
            ConfigurationFactory configurations,
            TestExecutionPlan.Command command) throws IOException, InterruptedException {
        configureLogs(context);
        ClassLoader classLoader = createClassLoader(context, configurations);
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(classLoader);
            GateProfile profile = loadProfile(context, classLoader, command.getCommandTokens().get(ARG_PROFILE));
            execute0(context, classLoader, profile, command);
        } finally {
            Thread.currentThread().setContextClassLoader(contextClassLoader);
            closeQuietly(classLoader);
        }
    }

    /**
     * Executes WindGate tasks internally.
     * @param context the current test context
     * @param classLoader the class loader for this execution
     * @param profile the target WindGate profile
     * @param command the command information
     * @throws IOException if failed to execute the command
     * @throws InterruptedException if interrupted while processing the command
     */
    protected abstract void execute0(
            TestDriverContext context,
            ClassLoader classLoader,
            GateProfile profile,
            TestExecutionPlan.Command command) throws IOException, InterruptedException;

    private static void configureLogs(TestDriverContext context) {
        MDC.put("batchId", context.getCurrentBatchId());
        MDC.put("flowId", context.getCurrentBatchId());
        MDC.put("executionId", context.getCurrentBatchId());
    }

    private static ClassLoader createClassLoader(
            TestDriverContext context,
            ConfigurationFactory configurations) throws IOException {
        final ClassLoader parent = configurations.newInstance().getClassLoader();
        final List<URL> libraries = new ArrayList<URL>();
        libraries.add(new File(context.getFrameworkHomePath(), PATH_CONF).toURI().toURL());
        libraries.add(EmulatorUtils.getJobflowLibraryPath(context).toURI().toURL());
        for (File file : EmulatorUtils.getBatchLibraryPaths(context)) {
            libraries.add(file.toURI().toURL());
        }
        File plugins = new File(context.getFrameworkHomePath(), PATH_PLUGIN);
        if (plugins.isDirectory()) {
            for (File file : plugins.listFiles()) {
                if (file.isFile()) {
                    libraries.add(file.toURI().toURL());
                }
            }
        }
        return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
            @Override
            public ClassLoader run() {
                return new URLClassLoader(libraries.toArray(new URL[libraries.size()]), parent);
            }
        });
    }

    private static GateProfile loadProfile(
            TestDriverContext context,
            ClassLoader classLoader,
            String profile) {
        LOG.debug("Loading profile: {}", profile);
        try {
            File profilePath = new File(
                    context.getFrameworkHomePath(),
                    MessageFormat.format(PATTERN_PROFILE, profile)).getAbsoluteFile();
            Map<String, String> variables = new HashMap<String, String>(context.getEnvironmentVariables());
            variables.put("WINDGATE_PROFILE", profile);
            ParameterList contextParameters = new ParameterList(variables);
            ProfileContext profileContext = new ProfileContext(classLoader, contextParameters);

            URI uri = profilePath.toURI();
            Properties properties = CommandLineUtil.loadProperties(uri, classLoader);
            return GateProfile.loadFrom(CommandLineUtil.toName(uri), properties, profileContext);
        } catch (Exception e) {
            throw new IllegalArgumentException(MessageFormat.format(
                    "Invalid profile \"{0}\".",
                    profile), e);
        }
    }

    static void closeQuietly(ClassLoader object) {
        if (object instanceof Closeable) {
            try {
                ((Closeable) object).close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
TOP

Related Classes of com.asakusafw.testdriver.windgate.emulation.AbstractWindGateCommandEmulator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.