Search in sources :

Example 1 with AbstractListener

use of co.cask.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class WorkflowTest method testOneActionWorkflow.

@Test(timeout = 120 * 1000L)
public void testOneActionWorkflow() throws Exception {
    final ApplicationWithPrograms app = AppFabricTestHelper.deployApplicationWithManager(OneActionWorkflowApp.class, TEMP_FOLDER_SUPPLIER);
    final Injector injector = AppFabricTestHelper.getInjector();
    final ProgramDescriptor programDescriptor = Iterators.filter(app.getPrograms().iterator(), new Predicate<ProgramDescriptor>() {

        @Override
        public boolean apply(ProgramDescriptor input) {
            return input.getProgramId().getType() == ProgramType.WORKFLOW;
        }
    }).next();
    final SettableFuture<String> completion = SettableFuture.create();
    final ProgramController controller = AppFabricTestHelper.submit(app, programDescriptor.getSpecification().getClassName(), new BasicArguments(), TEMP_FOLDER_SUPPLIER);
    controller.addListener(new AbstractListener() {

        @Override
        public void init(ProgramController.State currentState, @Nullable Throwable cause) {
            LOG.info("Initializing");
            injector.getInstance(Store.class).setStart(controller.getProgramRunId().getParent(), controller.getProgramRunId().getRun(), System.currentTimeMillis());
        }

        @Override
        public void completed() {
            LOG.info("Completed");
            completion.set("Completed");
        }

        @Override
        public void error(Throwable cause) {
            LOG.info("Error", cause);
            completion.setException(cause);
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    String run = completion.get();
    Assert.assertEquals("Completed", run);
}
Also used : ProgramController(co.cask.cdap.app.runtime.ProgramController) ApplicationWithPrograms(co.cask.cdap.internal.app.deploy.pipeline.ApplicationWithPrograms) Injector(com.google.inject.Injector) AbstractListener(co.cask.cdap.internal.app.runtime.AbstractListener) ProgramDescriptor(co.cask.cdap.app.program.ProgramDescriptor) BasicArguments(co.cask.cdap.internal.app.runtime.BasicArguments) Predicate(com.google.common.base.Predicate) Test(org.junit.Test)

Example 2 with AbstractListener

use of co.cask.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class WorkflowProgramRunner method run.

@Override
public ProgramController run(final Program program, final ProgramOptions options) {
    // Extract and verify options
    ApplicationSpecification appSpec = program.getApplicationSpecification();
    Preconditions.checkNotNull(appSpec, "Missing application specification.");
    ProgramType processorType = program.getType();
    Preconditions.checkNotNull(processorType, "Missing processor type.");
    Preconditions.checkArgument(processorType == ProgramType.WORKFLOW, "Only WORKFLOW process type is supported.");
    WorkflowSpecification workflowSpec = appSpec.getWorkflows().get(program.getName());
    Preconditions.checkNotNull(workflowSpec, "Missing WorkflowSpecification for %s", program.getName());
    final RunId runId = ProgramRunners.getRunId(options);
    // Setup dataset framework context, if required
    if (datasetFramework instanceof ProgramContextAware) {
        ProgramId programId = program.getId();
        ((ProgramContextAware) datasetFramework).setContext(new BasicProgramContext(programId.run(runId)));
    }
    // List of all Closeable resources that needs to be cleanup
    final List<Closeable> closeables = new ArrayList<>();
    try {
        PluginInstantiator pluginInstantiator = createPluginInstantiator(options, program.getClassLoader());
        if (pluginInstantiator != null) {
            closeables.add(pluginInstantiator);
        }
        WorkflowDriver driver = new WorkflowDriver(program, options, hostname, workflowSpec, programRunnerFactory, metricsCollectionService, datasetFramework, discoveryServiceClient, txClient, runtimeStore, cConf, pluginInstantiator, secureStore, secureStoreManager, messagingService);
        // Controller needs to be created before starting the driver so that the state change of the driver
        // service can be fully captured by the controller.
        final ProgramController controller = new WorkflowProgramController(program, driver, serviceAnnouncer, runId);
        final String twillRunId = options.getArguments().getOption(ProgramOptionConstants.TWILL_RUN_ID);
        controller.addListener(new AbstractListener() {

            @Override
            public void init(ProgramController.State state, @Nullable Throwable cause) {
                // Get start time from RunId
                long startTimeInSeconds = RunIds.getTime(controller.getRunId(), TimeUnit.SECONDS);
                if (startTimeInSeconds == -1) {
                    // If RunId is not time-based, use current time as start time
                    startTimeInSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
                }
                final long finalStartTimeInSeconds = startTimeInSeconds;
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        runtimeStore.setStart(program.getId(), runId.getId(), finalStartTimeInSeconds, twillRunId, options.getUserArguments().asMap(), options.getArguments().asMap());
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
                // This can happen if there is a delay in calling the init listener
                if (state == ProgramController.State.COMPLETED) {
                    completed();
                }
                // This can happen if there is a delay in calling the init listener
                if (state == ProgramController.State.ERROR) {
                    error(controller.getFailureCause());
                }
            }

            @Override
            public void completed() {
                LOG.debug("Program {} with run id {} completed successfully.", program.getId(), runId.getId());
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        runtimeStore.setStop(program.getId(), runId.getId(), TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), ProgramController.State.COMPLETED.getRunStatus());
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void killed() {
                LOG.debug("Program {} with run id {} killed.", program.getId(), runId.getId());
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        runtimeStore.setStop(program.getId(), runId.getId(), TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), ProgramController.State.KILLED.getRunStatus());
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void suspended() {
                LOG.debug("Suspending Program {} with run id {}.", program.getId(), runId.getId());
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        runtimeStore.setSuspend(program.getId(), runId.getId());
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void resuming() {
                LOG.debug("Resuming Program {} {}.", program.getId(), runId.getId());
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        runtimeStore.setResume(program.getId(), runId.getId());
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void error(final Throwable cause) {
                LOG.info("Program {} with run id {} stopped because of error {}.", program.getId(), runId.getId(), cause);
                closeAllQuietly(closeables);
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        runtimeStore.setStop(program.getId(), runId.getId(), TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), ProgramController.State.ERROR.getRunStatus(), new BasicThrowable(cause));
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }
        }, Threads.SAME_THREAD_EXECUTOR);
        driver.start();
        return controller;
    } catch (Exception e) {
        closeAllQuietly(closeables);
        throw Throwables.propagate(e);
    }
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) ProgramController(co.cask.cdap.app.runtime.ProgramController) Closeable(java.io.Closeable) ArrayList(java.util.ArrayList) ProgramId(co.cask.cdap.proto.id.ProgramId) BasicProgramContext(co.cask.cdap.internal.app.runtime.BasicProgramContext) WorkflowSpecification(co.cask.cdap.api.workflow.WorkflowSpecification) BasicThrowable(co.cask.cdap.proto.BasicThrowable) PluginInstantiator(co.cask.cdap.internal.app.runtime.plugin.PluginInstantiator) AbstractListener(co.cask.cdap.internal.app.runtime.AbstractListener) Supplier(com.google.common.base.Supplier) ProgramType(co.cask.cdap.proto.ProgramType) RunId(org.apache.twill.api.RunId) BasicThrowable(co.cask.cdap.proto.BasicThrowable) ProgramContextAware(co.cask.cdap.data.ProgramContextAware)

Example 3 with AbstractListener

use of co.cask.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class WorkerProgramRunnerTest method stopProgram.

private void stopProgram(ProgramController controller) throws Throwable {
    final AtomicReference<Throwable> errorCause = new AtomicReference<>();
    final CountDownLatch complete = new CountDownLatch(1);
    controller.addListener(new AbstractListener() {

        @Override
        public void error(Throwable cause) {
            complete.countDown();
            errorCause.set(cause);
        }

        @Override
        public void completed() {
            complete.countDown();
        }

        @Override
        public void killed() {
            complete.countDown();
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    controller.stop();
    complete.await(30, TimeUnit.SECONDS);
    runningPrograms.remove(controller);
    Throwable t = errorCause.get();
    if (t != null) {
        throw t;
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) AbstractListener(co.cask.cdap.internal.app.runtime.AbstractListener) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 4 with AbstractListener

use of co.cask.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class ProgramLifecycleService method start.

/**
   * Start a Program.
   *
   * @param programId  the {@link ProgramId program} to start
   * @param systemArgs system arguments
   * @param userArgs user arguments
   * @param debug enable debug mode
   * @return {@link ProgramRuntimeService.RuntimeInfo}
   * @throws IOException if there is an error starting the program
   * @throws ProgramNotFoundException if program is not found
   * @throws UnauthorizedException if the logged in user is not authorized to start the program. To start a program,
   *                               a user requires {@link Action#EXECUTE} on the program
   * @throws Exception if there were other exceptions checking if the current user is authorized to start the program
   */
public ProgramRuntimeService.RuntimeInfo start(final ProgramId programId, final Map<String, String> systemArgs, final Map<String, String> userArgs, boolean debug) throws Exception {
    authorizationEnforcer.enforce(programId, authenticationContext.getPrincipal(), Action.EXECUTE);
    ProgramDescriptor programDescriptor = store.loadProgram(programId);
    BasicArguments systemArguments = new BasicArguments(systemArgs);
    BasicArguments userArguments = new BasicArguments(userArgs);
    ProgramRuntimeService.RuntimeInfo runtimeInfo = runtimeService.run(programDescriptor, new SimpleProgramOptions(programId.getProgram(), systemArguments, userArguments, debug));
    final ProgramController controller = runtimeInfo.getController();
    final String runId = controller.getRunId().getId();
    final String twillRunId = runtimeInfo.getTwillRunId() == null ? null : runtimeInfo.getTwillRunId().getId();
    if (programId.getType() != ProgramType.MAPREDUCE && programId.getType() != ProgramType.SPARK && programId.getType() != ProgramType.WORKFLOW) {
        // MapReduce state recording is done by the MapReduceProgramRunner, Spark state recording
        // is done by SparkProgramRunner, and Workflow state recording is done by WorkflowProgramRunner.
        // TODO [JIRA: CDAP-2013] Same needs to be done for other programs as well
        controller.addListener(new AbstractListener() {

            @Override
            public void init(ProgramController.State state, @Nullable Throwable cause) {
                // Get start time from RunId
                long startTimeInSeconds = RunIds.getTime(controller.getRunId(), TimeUnit.SECONDS);
                if (startTimeInSeconds == -1) {
                    // If RunId is not time-based, use current time as start time
                    startTimeInSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
                }
                final long finalStartTimeInSeconds = startTimeInSeconds;
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        store.setStart(programId, runId, finalStartTimeInSeconds, twillRunId, userArgs, systemArgs);
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
                if (state == ProgramController.State.COMPLETED) {
                    completed();
                }
                if (state == ProgramController.State.ERROR) {
                    error(controller.getFailureCause());
                }
            }

            @Override
            public void completed() {
                LOG.debug("Program {} completed successfully.", programId);
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        store.setStop(programId, runId, TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), ProgramController.State.COMPLETED.getRunStatus());
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void killed() {
                LOG.debug("Program {} killed.", programId);
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        store.setStop(programId, runId, TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), ProgramController.State.KILLED.getRunStatus());
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void suspended() {
                LOG.debug("Suspending Program {} {}.", programId, runId);
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        store.setSuspend(programId, runId);
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void resuming() {
                LOG.debug("Resuming Program {} {}.", programId, runId);
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        store.setResume(programId, runId);
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }

            @Override
            public void error(final Throwable cause) {
                LOG.info("Program stopped with error {}, {}", programId, runId, cause);
                Retries.supplyWithRetries(new Supplier<Void>() {

                    @Override
                    public Void get() {
                        store.setStop(programId, runId, TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), ProgramController.State.ERROR.getRunStatus(), new BasicThrowable(cause));
                        return null;
                    }
                }, RetryStrategies.fixDelay(Constants.Retry.RUN_RECORD_UPDATE_RETRY_DELAY_SECS, TimeUnit.SECONDS));
            }
        }, Threads.SAME_THREAD_EXECUTOR);
    }
    return runtimeInfo;
}
Also used : ProgramController(co.cask.cdap.app.runtime.ProgramController) RuntimeInfo(co.cask.cdap.app.runtime.ProgramRuntimeService.RuntimeInfo) BasicThrowable(co.cask.cdap.proto.BasicThrowable) AbstractListener(co.cask.cdap.internal.app.runtime.AbstractListener) Supplier(com.google.common.base.Supplier) ProgramDescriptor(co.cask.cdap.app.program.ProgramDescriptor) BasicArguments(co.cask.cdap.internal.app.runtime.BasicArguments) SimpleProgramOptions(co.cask.cdap.internal.app.runtime.SimpleProgramOptions) BasicThrowable(co.cask.cdap.proto.BasicThrowable) ProgramRuntimeService(co.cask.cdap.app.runtime.ProgramRuntimeService)

Example 5 with AbstractListener

use of co.cask.cdap.internal.app.runtime.AbstractListener in project cdap by caskdata.

the class MapReduceRunnerTestBase method waitForCompletion.

private boolean waitForCompletion(ProgramController controller) throws InterruptedException {
    final AtomicBoolean success = new AtomicBoolean(false);
    final CountDownLatch completion = new CountDownLatch(1);
    controller.addListener(new AbstractListener() {

        @Override
        public void completed() {
            success.set(true);
            completion.countDown();
        }

        @Override
        public void error(Throwable cause) {
            completion.countDown();
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    // MR tests can run for long time.
    completion.await(10, TimeUnit.MINUTES);
    return success.get();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AbstractListener(co.cask.cdap.internal.app.runtime.AbstractListener) CountDownLatch(java.util.concurrent.CountDownLatch)

Aggregations

AbstractListener (co.cask.cdap.internal.app.runtime.AbstractListener)13 ProgramController (co.cask.cdap.app.runtime.ProgramController)9 BasicArguments (co.cask.cdap.internal.app.runtime.BasicArguments)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 ProgramDescriptor (co.cask.cdap.app.program.ProgramDescriptor)3 BasicThrowable (co.cask.cdap.proto.BasicThrowable)3 Test (org.junit.Test)3 ProgramRuntimeService (co.cask.cdap.app.runtime.ProgramRuntimeService)2 ApplicationWithPrograms (co.cask.cdap.internal.app.deploy.pipeline.ApplicationWithPrograms)2 ApplicationId (co.cask.cdap.proto.id.ApplicationId)2 ProgramId (co.cask.cdap.proto.id.ProgramId)2 Predicate (com.google.common.base.Predicate)2 Supplier (com.google.common.base.Supplier)2 Injector (com.google.inject.Injector)2 Closeable (java.io.Closeable)2 IOException (java.io.IOException)2 ExecutionException (java.util.concurrent.ExecutionException)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 ApplicationSpecification (co.cask.cdap.api.app.ApplicationSpecification)1 ArtifactSummary (co.cask.cdap.api.artifact.ArtifactSummary)1