All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.arquillian.spacelift.task.os.ProcessBasedExecution Maven / Gradle / Ivy

There is a newer version: 1.0.2
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2014, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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 org.arquillian.spacelift.task.os;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.arquillian.spacelift.execution.CountDownWatch;
import org.arquillian.spacelift.execution.Execution;
import org.arquillian.spacelift.execution.ExecutionCondition;
import org.arquillian.spacelift.execution.ExecutionException;
import org.arquillian.spacelift.execution.TimeoutExecutionException;
import org.arquillian.spacelift.execution.impl.ShutdownHooks;

/**
 * Representation of a process execution.
 *
 * @author Karel Piwko
 *
 */
public class ProcessBasedExecution implements Execution {
    private static final Logger log = Logger.getLogger(ProcessBasedExecution.class.getName());

    private final Execution processFutureExecution;
    private final ProcessReference processReference;
    private final String processName;
    private final List allowedExitCodes;

    private boolean shouldBeFinished;

    /**
     * Creates a process execution, add a name to the process
     *
     * @param processFutureExecution
     * @param processName
     */
    public ProcessBasedExecution(Execution processFutureExecution, ProcessReference processReference, String processName, List allowedExitCodes) {
        this.processFutureExecution = processFutureExecution;
        this.processReference = processReference;
        this.processName = processName;
        this.allowedExitCodes = new ArrayList(allowedExitCodes);
    }

    @Override
    public boolean isFinished() {

        // if process is marked as finished, consider it so
        if (isMarkedAsFinished()) {
            return true;
        }

        try {
            if (!processReference.isInitialized()) {
                return false;
            }
            processReference.getProcess().exitValue();
            return true;
        } catch (IllegalThreadStateException e) {
            return false;
        }
    }

    @Override
    public boolean isMarkedAsFinished() {
        return shouldBeFinished;
    }

    @Override
    public Execution terminate() throws ExecutionException {

        // if process has not yet started, terminate Future that would lead to its creation
        if (!processReference.isInitialized()) {
            processFutureExecution.terminate();
            return markAsFinished();
        }

        processReference.getProcess().destroy();
        try {
            processReference.getProcess().waitFor();
        } catch (InterruptedException e) {
            log.log(Level.WARNING, "Ignoring Interuption Exception while terminating the process {0}", processName);
        }

        // close STDIN of the process, if any
        OutputStream ostream = processReference.getProcess().getOutputStream();
        try {
            if (ostream != null) {
                ostream.flush();
                ostream.close();
            }
        } catch (IOException e) {
            log.log(Level.WARNING, "Ignoring IO exception while terminating the process {0}", processName);
        }

        return this;
    }

    @Override
    public Execution markAsFinished() {
        this.shouldBeFinished = true;
        return this;
    }

    @Override
    public Execution registerShutdownHook() {
        ShutdownHooks.addHookFor(this);
        return this;
    }

    @Override
    public boolean hasFailed() {
        if (!isFinished()) {
            throw new IllegalStateException("Process " + processName
                + " is not yet finished, cannot determine whether it failed.");
        }

        // check whether we have specified exit value and if not adhere to defaults
        if (allowedExitCodes.isEmpty()) {
            return processReference.getProcess().exitValue() != 0;
        }

        return !allowedExitCodes.contains(processReference.getProcess().exitValue());
    }

    @Override
    public RESULT await() throws ExecutionException {
        if (processFutureExecution.hasFailed()) {
            return null;
        }
        return processFutureExecution.await();

    }

    @Override
    public RESULT awaitAtMost(long timeout, TimeUnit unit) throws ExecutionException, TimeoutExecutionException {
        if (processFutureExecution.hasFailed()) {
            return null;
        }
        return processFutureExecution.awaitAtMost(timeout, unit);
    }

    @Override
    public Execution reexecuteEvery(long step, TimeUnit unit) {
        processFutureExecution.reexecuteEvery(step, unit);
        return this;
    }

    @Override
    public RESULT until(long timeout, TimeUnit unit, ExecutionCondition condition) throws ExecutionException,
        TimeoutExecutionException {

        return processFutureExecution.until(timeout, unit, condition);
    }

    @Override
    public RESULT awaitAtMost(CountDownWatch timeout) throws ExecutionException, TimeoutExecutionException {
        return awaitAtMost(timeout.timeout(), timeout.getTimeUnit());
    }

    @Override
    public RESULT until(CountDownWatch timeout, ExecutionCondition condition) throws ExecutionException, TimeoutExecutionException {
        return until(timeout.timeout(), timeout.getTimeUnit(), condition);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy