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

org.infrastructurebuilder.util.MutableProcessExecutionResultBag Maven / Gradle / Ivy

There is a newer version: 0.17.3
Show newest version
/**
 * Copyright © 2019 admin ([email protected])
 *
 * 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.infrastructurebuilder.util;

import static java.time.Duration.between;
import static java.time.Instant.now;
import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;

import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import org.infrastructurebuilder.util.execution.model.v1_0_0.DefaultProcessExecutionResult;
import org.zeroturnaround.exec.ProcessExecutor;
import org.zeroturnaround.exec.ProcessResult;
import org.zeroturnaround.exec.listener.ProcessListener;

public class MutableProcessExecutionResultBag extends ProcessListener {
  private final ConcurrentMap                   endTimes    = new ConcurrentHashMap<>();
  private final ConcurrentMap                 exceptions  = new ConcurrentHashMap<>();
  private final List                                     executedIds = new ArrayList<>();
//  private final ConcurrentMap executors   = new ConcurrentHashMap<>();
  private final Vector                            executors2  = new Vector<>();
  private final ConcurrentMap                   exitCodes   = new ConcurrentHashMap<>();
  private final ConcurrentMap>     futures     = new ConcurrentHashMap<>();
  private final ConcurrentMap                   processes   = new ConcurrentHashMap<>();
  private final ConcurrentMap                   startTimes  = new ConcurrentHashMap<>();

  public void addExecution(final ProcessExecution pe, final ProcessExecutor pExecutor) {
    synchronized (executedIds) {
      executors2.add(pe);
//      executors.put(requireNonNull(pe), requireNonNull(pExecutor));
      executedIds.add(pe.getId());
    }
  }

  public MutableProcessExecutionResultBag addFuture(final ProcessExecution pe, final Future future) {
    futures.put(requireNonNull(pe).getId(), requireNonNull(future));
    return this;
  }

  public void addProcess(final ProcessExecution pe, final Process process) {
    processes.put(requireNonNull(pe).getId(), requireNonNull(process));

  }

  @Override
  public void afterFinish(final Process process, final ProcessResult result) {
    afterStop(process);
    processes.entrySet().stream().filter(e -> e.getValue() == process).map(ee -> ee.getKey()).findFirst()
        .ifPresent(pe -> {
          endTimes.put(pe, now());
          exitCodes.put(pe, result.getExitValue());
        });

  }

  @Override
  public void afterStart(final Process process, final ProcessExecutor executor) {
    super.afterStart(process, executor);
  }

  @Override
  public void afterStop(final Process process) {
    processes.entrySet().stream().filter(e -> e.getValue() == process).map(ee -> ee.getKey()).findFirst()
        .ifPresent(pe -> {
          endTimes.put(pe, now());
          exitCodes.put(pe, process.exitValue());
        });

  }

  @Override
  public void beforeStart(final ProcessExecutor executor) {
    requireNonNull(executor);
//    executors.entrySet().stream().filter(e -> e.getValue() == executor).map(e -> e.getKey()).findFirst()
//    .ifPresent(ee -> {
//      startTimes.put(ee.getId(), now());
//    });
    executors2.stream().filter(e -> e.getProcessExecutor() == executor).findFirst()
    .ifPresent(ee -> {
      startTimes.put(ee.getId(), now());
    });
  }

  public boolean destroyRemainingSleepers(final Optional sleepAfter) {
    requireNonNull(sleepAfter);
    for (final String p : getRunningFutures().keySet()) {
      processes.get(p).destroy();
    }
    for (final Future p : getRunningFutures().values()) {
      p.cancel(false);
    }
    final long sleep = sleepAfter.orElse(0L);
    try {
      Thread.sleep(sleep);
    } catch (final InterruptedException e) {
    }
    boolean retVal = false;
    for (final Future p : getRunningFutures().values()) {
      retVal |= p.cancel(true);
    }
    return retVal;
  }

  public List getExecutedIds() {
    return executedIds;
  }

  public Map getExecutionResults() {
    synchronized (executedIds) {
      final Map m = new HashMap<>();
      for (final ProcessExecution pe : executors2) {
//        for (final ProcessExecution pe : executors.keySet()) {
        final String id = pe.getId();
        final Instant startTime = ofNullable(startTimes.get(id)).orElse(null);
        final Instant endTime = ofNullable(endTimes.get(id)).orElse(Instant.MAX);
        final Optional exitCode = ofNullable(exitCodes.get(id));
        final Optional exception = ofNullable(exceptions.get(id));
        m.put(id, new DefaultProcessExecutionResult(pe, exitCode, exception, startTime,
            between(startTime, endTime)));
      }
      return m;
    }
  }

  public Map> getFutures() {
    return futures;
  }

  public DefaultProcessExecutionResultBag lock() {
    return new DefaultProcessExecutionResultBag(this);
  }

  public void setException(final ProcessExecution pe, final Throwable t) {
    exceptions.put(requireNonNull(pe).getId(), requireNonNull(t));

  }

  public boolean stillRunning() {
    return getRunningFutures().values().stream().findAny().isPresent();
  }

  Map> getRunningFutures() {
    return getFutures().entrySet().stream().filter(e -> !e.getValue().isDone())
        .collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue()));
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy