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

com.cognifide.aet.runner.processing.SuiteProcessor Maven / Gradle / Ivy

/**
 * AET
 *
 * Copyright (C) 2013 Cognifide Limited
 *
 * 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.cognifide.aet.runner.processing;

import com.cognifide.aet.communication.api.ProcessingError;
import com.cognifide.aet.communication.api.messages.ProcessingErrorMessage;
import com.cognifide.aet.communication.api.messages.ProgressMessage;
import com.cognifide.aet.communication.api.util.ExecutionTimer;
import com.cognifide.aet.runner.RunnerConfiguration;
import com.cognifide.aet.runner.processing.data.SuiteIndexWrapper;
import com.cognifide.aet.runner.processing.steps.CollectDispatcher;
import com.cognifide.aet.runner.processing.steps.CollectionResultsRouter;
import com.cognifide.aet.runner.processing.steps.ComparisonResultsRouter;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.jms.JMSException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class contains the actual logic around runner suite processing.
 */
class SuiteProcessor {

  private static final Logger LOGGER = LoggerFactory.getLogger(SuiteProcessor.class);

  private final ExecutionTimer timer;
  private boolean processed;
  private final TimeoutWatch timeoutWatch;
  private final CollectDispatcher collectDispatcher;
  private final CollectionResultsRouter collectionResultsRouter;
  private final ComparisonResultsRouter comparisonResultsRouter;
  private final SuiteIndexWrapper indexedSuite;
  private final RunnerConfiguration runnerConfiguration;
  private final MessagesSender messagesSender;

  SuiteProcessor(SuiteExecutionFactory suiteExecutionFactory,
      SuiteIndexWrapper indexedSuite, RunnerConfiguration runnerConfiguration,
      MessagesSender messagesSender) throws JMSException {
    this.indexedSuite = indexedSuite;
    this.runnerConfiguration = runnerConfiguration;
    this.messagesSender = messagesSender;
    this.timeoutWatch = new TimeoutWatch();
    timer = ExecutionTimer.createAndRun("RUNNER");
    collectDispatcher = suiteExecutionFactory.newCollectDispatcher(timeoutWatch, this.indexedSuite);
    collectionResultsRouter = suiteExecutionFactory
        .newCollectionResultsRouter(timeoutWatch, this.indexedSuite);
    comparisonResultsRouter = suiteExecutionFactory
        .newComparisonResultsRouter(timeoutWatch, this.indexedSuite);
    collectionResultsRouter.addObserver(messagesSender);
    comparisonResultsRouter.addObserver(messagesSender);
    collectionResultsRouter.addChangeObserver(comparisonResultsRouter);
  }

  void startProcessing() throws JMSException {
    timeoutWatch.update();
    if (tryProcess()) {
      checkStatusUntilFinishedOrTimedOut();
      if (comparisonResultsRouter.isFinished()) {
        timer.finish();
        LOGGER.info("Finished suite run: {}. Task finished in {} ms ({}).",
            indexedSuite.get().getCorrelationId(), timer.getExecutionTimeInMillis(),
            timer.getExecutionTimeInMMSS());
        LOGGER.info("Total tasks finished in steps: collect: {}; compare: {}.",
            collectionResultsRouter.getTotalTasksCount(),
            comparisonResultsRouter.getTotalTasksCount());
      } else if (suiteIsTimedOut()) {
        timer.finish();
        LOGGER.warn(
            "Running {} interrupted after {} ms ({}). Last message received: {} seconds ago... Trying to force report generation.",
            indexedSuite.get().getCorrelationId(), timer.getExecutionTimeInMillis(),
            timer.getExecutionTimeInMMSS(),
            TimeUnit.NANOSECONDS.toSeconds(timeoutWatch.getLastUpdateDifference()));
        forceFinishSuite();
      }
    }
  }

  void cleanup() {
    comparisonResultsRouter.closeConnections();
    collectionResultsRouter.closeConnections();
    collectDispatcher.closeConnections();
  }

  private boolean suiteIsTimedOut() {
    return timeoutWatch.isTimedOut(runnerConfiguration.getFt());
  }

  private void checkStatusUntilFinishedOrTimedOut() {
    String logMessage = "";
    while (!comparisonResultsRouter.isFinished() && !timeoutWatch
        .isTimedOut(runnerConfiguration.getFt())) {
      try {
        String currentLog = composeProgressLog();
        if (!currentLog.equals(logMessage)) {
          logMessage = currentLog;
          LOGGER.info("[{}]: {}", indexedSuite.get().getCorrelationId(), logMessage);
          messagesSender.sendMessage(new ProgressMessage(logMessage));
        }
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }
  }

  private String composeProgressLog() {
    ProgressLog compareLog = collectionResultsRouter.getProgress();
    ProgressLog reportLog = comparisonResultsRouter.getProgress();
    return StringUtils.join(Arrays.asList(compareLog, reportLog), " ::: ");
  }

  private synchronized boolean tryProcess() throws JMSException {
    boolean result = !processed;
    if (!processed) {
      collectDispatcher.process();
      processed = true;
    }
    return result;
  }

  private void forceFinishSuite() {
    messagesSender.sendMessage(new ProcessingErrorMessage(ProcessingError
        .reportingError(
            "Report will be generated after timeout - some results might be missing!"),
        indexedSuite.get().getCorrelationId()));
    timeoutWatch.update();
    checkStatusUntilFinishedOrTimedOut();
    if (!comparisonResultsRouter.isFinished()) {
      comparisonResultsRouter.abort();
      messagesSender.sendMessage(new ProcessingErrorMessage(ProcessingError
          .reportingError(
              "Report will be generated after timeout - some results might be missing!"),
          indexedSuite.get().getCorrelationId()));
    }
    collectDispatcher.cancel(indexedSuite.get().getCorrelationId());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy