Search in sources :

Example 1 with ProgramController

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

the class FlowProgramRunner method run.

@Override
public ProgramController run(Program program, ProgramOptions options) {
    // Extract and verify parameters
    ApplicationSpecification appSpec = program.getApplicationSpecification();
    Preconditions.checkNotNull(appSpec, "Missing application specification.");
    ProgramType processorType = program.getType();
    Preconditions.checkNotNull(processorType, "Missing processor type.");
    Preconditions.checkArgument(processorType == ProgramType.FLOW, "Only FLOW process type is supported.");
    FlowSpecification flowSpec = appSpec.getFlows().get(program.getName());
    Preconditions.checkNotNull(flowSpec, "Missing FlowSpecification for %s", program.getName());
    try {
        // Launch flowlet program runners
        RunId runId = ProgramRunners.getRunId(options);
        Multimap<String, QueueName> consumerQueues = FlowUtils.configureQueue(program, flowSpec, streamAdmin, queueAdmin, txExecutorFactory);
        final Table<String, Integer, ProgramController> flowlets = createFlowlets(program, options, flowSpec);
        return new FlowProgramController(flowlets, program, options, flowSpec, consumerQueues);
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) ProgramController(co.cask.cdap.app.runtime.ProgramController) AbstractProgramController(co.cask.cdap.internal.app.runtime.AbstractProgramController) FlowSpecification(co.cask.cdap.api.flow.FlowSpecification) ProgramType(co.cask.cdap.proto.ProgramType) RunId(org.apache.twill.api.RunId) QueueName(co.cask.cdap.common.queue.QueueName) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with ProgramController

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

the class FlowProgramRunner method createFlowlets.

/**
   * Starts all flowlets in the flow program.
   * @param program Program to run
   * @param flowSpec The {@link FlowSpecification}.
   * @return A {@link Table} with row as flowlet id, column as instance id, cell as the {@link ProgramController}
   *         for the flowlet.
   */
private Table<String, Integer, ProgramController> createFlowlets(Program program, ProgramOptions options, FlowSpecification flowSpec) {
    Table<String, Integer, ProgramController> flowlets = HashBasedTable.create();
    try {
        for (Map.Entry<String, FlowletDefinition> entry : flowSpec.getFlowlets().entrySet()) {
            ProgramOptions flowletOptions = resolveFlowletOptions(options, entry.getKey());
            int instanceCount = entry.getValue().getInstances();
            for (int instanceId = 0; instanceId < instanceCount; instanceId++) {
                flowlets.put(entry.getKey(), instanceId, startFlowlet(program, createFlowletOptions(entry.getKey(), instanceId, instanceCount, flowletOptions)));
            }
        }
    } catch (Throwable t) {
        try {
            // Need to stop all started flowlets
            Futures.successfulAsList(Iterables.transform(flowlets.values(), new Function<ProgramController, ListenableFuture<?>>() {

                @Override
                public ListenableFuture<?> apply(ProgramController controller) {
                    return controller.stop();
                }
            })).get();
        } catch (Exception e) {
            LOG.error("Fail to stop all flowlets on failure.");
        }
        throw Throwables.propagate(t);
    }
    return flowlets;
}
Also used : FlowletDefinition(co.cask.cdap.api.flow.FlowletDefinition) Function(com.google.common.base.Function) ProgramController(co.cask.cdap.app.runtime.ProgramController) AbstractProgramController(co.cask.cdap.internal.app.runtime.AbstractProgramController) HashMap(java.util.HashMap) Map(java.util.Map) SimpleProgramOptions(co.cask.cdap.internal.app.runtime.SimpleProgramOptions) ProgramOptions(co.cask.cdap.app.runtime.ProgramOptions) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with ProgramController

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

the class ProgramLifecycleService method stop.

/**
   * Stops the specified run of the specified program.
   *
   * @param programId the {@link ProgramId program} to stop
   * @param runId the runId of the program run to stop. If null, all runs of the program as returned by
   *              {@link ProgramRuntimeService} are stopped.
   * @throws NotFoundException if the app, program or run was not found
   * @throws BadRequestException if an attempt is made to stop a program that is either not running or
   *                             was started by a workflow
   * @throws InterruptedException if there was a problem while waiting for the stop call to complete
   * @throws ExecutionException if there was a problem while waiting for the stop call to complete
   */
public void stop(ProgramId programId, @Nullable String runId) throws Exception {
    List<ListenableFuture<ProgramController>> futures = issueStop(programId, runId);
    // Block until all stop requests completed. This call never throw ExecutionException
    Futures.successfulAsList(futures).get();
    Throwable failureCause = null;
    for (ListenableFuture<ProgramController> f : futures) {
        try {
            f.get();
        } catch (ExecutionException e) {
            // an IllegalStateException will be throw, which we can safely ignore
            if (!(e.getCause() instanceof IllegalStateException)) {
                if (failureCause == null) {
                    failureCause = e.getCause();
                } else {
                    failureCause.addSuppressed(e.getCause());
                }
            }
        }
    }
    if (failureCause != null) {
        throw new ExecutionException(String.format("%d out of %d runs of the program %s failed to stop", failureCause.getSuppressed().length + 1, futures.size(), programId), failureCause);
    }
}
Also used : ProgramController(co.cask.cdap.app.runtime.ProgramController) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) BasicThrowable(co.cask.cdap.proto.BasicThrowable) ExecutionException(java.util.concurrent.ExecutionException)

Example 4 with ProgramController

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

the class ProgramLifecycleServiceTest method testInvalidFlowRunRecord.

@Test
public void testInvalidFlowRunRecord() throws Exception {
    // Create App with Flow and the deploy
    HttpResponse response = deploy(WordCountApp.class, Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE1);
    Assert.assertEquals(200, response.getStatusLine().getStatusCode());
    final Id.Program wordcountFlow1 = Id.Program.from(TEST_NAMESPACE1, "WordCountApp", ProgramType.FLOW, "WordCountFlow");
    // flow is stopped initially
    Assert.assertEquals("STOPPED", getProgramStatus(wordcountFlow1));
    // start a flow and check the status
    startProgram(wordcountFlow1);
    waitState(wordcountFlow1, ProgramRunStatus.RUNNING.toString());
    // Wait until we have a run record
    Tasks.waitFor(1, new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
            return getProgramRuns(wordcountFlow1, ProgramRunStatus.RUNNING.toString()).size();
        }
    }, 5, TimeUnit.SECONDS);
    // Get the RunRecord
    List<RunRecord> runRecords = getProgramRuns(wordcountFlow1, ProgramRunStatus.RUNNING.toString());
    Assert.assertEquals(1, runRecords.size());
    final RunRecord rr = runRecords.get(0);
    // Check the RunRecords status
    Assert.assertEquals(ProgramRunStatus.RUNNING, rr.getStatus());
    // Lets set the runtime info to off
    RuntimeInfo runtimeInfo = runtimeService.lookup(wordcountFlow1.toEntityId(), RunIds.fromString(rr.getPid()));
    ProgramController programController = runtimeInfo.getController();
    programController.stop();
    // Verify that the status of that run is KILLED
    Tasks.waitFor(ProgramRunStatus.KILLED, new Callable<ProgramRunStatus>() {

        @Override
        public ProgramRunStatus call() throws Exception {
            RunRecordMeta runRecord = store.getRun(wordcountFlow1.toEntityId(), rr.getPid());
            return runRecord == null ? null : runRecord.getStatus();
        }
    }, 5, TimeUnit.SECONDS, 100, TimeUnit.MILLISECONDS);
    // Use the store manipulate state to be RUNNING
    long now = System.currentTimeMillis();
    long nowSecs = TimeUnit.MILLISECONDS.toSeconds(now);
    store.setStart(wordcountFlow1.toEntityId(), rr.getPid(), nowSecs);
    // Now check again via Store to assume data store is wrong.
    RunRecord runRecordMeta = store.getRun(wordcountFlow1.toEntityId(), rr.getPid());
    Assert.assertNotNull(runRecordMeta);
    Assert.assertEquals(ProgramRunStatus.RUNNING, runRecordMeta.getStatus());
    // Verify there is NO FAILED run record for the application
    runRecords = getProgramRuns(wordcountFlow1, ProgramRunStatus.FAILED.toString());
    Assert.assertEquals(0, runRecords.size());
    // Lets fix it
    Set<String> processedInvalidRunRecordIds = Sets.newHashSet();
    programLifecycleService.validateAndCorrectRunningRunRecords(ProgramType.FLOW, processedInvalidRunRecordIds);
    // Verify there is one FAILED run record for the application
    runRecords = getProgramRuns(wordcountFlow1, ProgramRunStatus.FAILED.toString());
    Assert.assertEquals(1, runRecords.size());
    Assert.assertEquals(ProgramRunStatus.FAILED, runRecords.get(0).getStatus());
}
Also used : ProgramController(co.cask.cdap.app.runtime.ProgramController) RuntimeInfo(co.cask.cdap.app.runtime.ProgramRuntimeService.RuntimeInfo) RunRecordMeta(co.cask.cdap.internal.app.store.RunRecordMeta) HttpResponse(org.apache.http.HttpResponse) RunRecord(co.cask.cdap.proto.RunRecord) ProgramRunStatus(co.cask.cdap.proto.ProgramRunStatus) Id(co.cask.cdap.proto.Id) Test(org.junit.Test)

Example 5 with ProgramController

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

the class SparkProgramRunner method run.

@Override
public ProgramController run(Program program, ProgramOptions options) {
    // Get the RunId first. It is used for the creation of the ClassLoader closing thread.
    Arguments arguments = options.getArguments();
    RunId runId = ProgramRunners.getRunId(options);
    Deque<Closeable> closeables = new LinkedList<>();
    try {
        // Extract and verify parameters
        ApplicationSpecification appSpec = program.getApplicationSpecification();
        Preconditions.checkNotNull(appSpec, "Missing application specification.");
        ProgramType processorType = program.getType();
        Preconditions.checkNotNull(processorType, "Missing processor type.");
        Preconditions.checkArgument(processorType == ProgramType.SPARK, "Only Spark process type is supported.");
        SparkSpecification spec = appSpec.getSpark().get(program.getName());
        Preconditions.checkNotNull(spec, "Missing SparkSpecification for %s", program.getName());
        String host = options.getArguments().getOption(ProgramOptionConstants.HOST);
        Preconditions.checkArgument(host != null, "No hostname is provided");
        // Get the WorkflowProgramInfo if it is started by Workflow
        WorkflowProgramInfo workflowInfo = WorkflowProgramInfo.create(arguments);
        DatasetFramework programDatasetFramework = workflowInfo == null ? datasetFramework : NameMappedDatasetFramework.createFromWorkflowProgramInfo(datasetFramework, workflowInfo, appSpec);
        // Setup dataset framework context, if required
        if (programDatasetFramework instanceof ProgramContextAware) {
            ProgramId programId = program.getId();
            ((ProgramContextAware) programDatasetFramework).setContext(new BasicProgramContext(programId.run(runId)));
        }
        PluginInstantiator pluginInstantiator = createPluginInstantiator(options, program.getClassLoader());
        if (pluginInstantiator != null) {
            closeables.addFirst(pluginInstantiator);
        }
        SparkRuntimeContext runtimeContext = new SparkRuntimeContext(new Configuration(hConf), program, options, cConf, host, txClient, programDatasetFramework, discoveryServiceClient, metricsCollectionService, streamAdmin, workflowInfo, pluginInstantiator, secureStore, secureStoreManager, authorizationEnforcer, authenticationContext, messagingService, serviceAnnouncer, pluginFinder, locationFactory);
        closeables.addFirst(runtimeContext);
        Spark spark;
        try {
            spark = new InstantiatorFactory(false).get(TypeToken.of(program.<Spark>getMainClass())).create();
        } catch (Exception e) {
            LOG.error("Failed to instantiate Spark class for {}", spec.getClassName(), e);
            throw Throwables.propagate(e);
        }
        SparkSubmitter submitter = SparkRuntimeContextConfig.isLocal(hConf) ? new LocalSparkSubmitter() : new DistributedSparkSubmitter(hConf, locationFactory, host, runtimeContext, options.getArguments().getOption(Constants.AppFabric.APP_SCHEDULER_QUEUE));
        Service sparkRuntimeService = new SparkRuntimeService(cConf, spark, getPluginArchive(options), runtimeContext, submitter, locationFactory);
        sparkRuntimeService.addListener(createRuntimeServiceListener(closeables), Threads.SAME_THREAD_EXECUTOR);
        ProgramController controller = new SparkProgramController(sparkRuntimeService, runtimeContext);
        LOG.debug("Starting Spark Job. Context: {}", runtimeContext);
        if (SparkRuntimeContextConfig.isLocal(hConf) || UserGroupInformation.isSecurityEnabled()) {
            sparkRuntimeService.start();
        } else {
            ProgramRunners.startAsUser(cConf.get(Constants.CFG_HDFS_USER), sparkRuntimeService);
        }
        return controller;
    } catch (Throwable t) {
        closeAllQuietly(closeables);
        throw Throwables.propagate(t);
    }
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) SparkSubmitter(co.cask.cdap.app.runtime.spark.submit.SparkSubmitter) DistributedSparkSubmitter(co.cask.cdap.app.runtime.spark.submit.DistributedSparkSubmitter) LocalSparkSubmitter(co.cask.cdap.app.runtime.spark.submit.LocalSparkSubmitter) CConfiguration(co.cask.cdap.common.conf.CConfiguration) Configuration(org.apache.hadoop.conf.Configuration) Closeable(java.io.Closeable) DistributedSparkSubmitter(co.cask.cdap.app.runtime.spark.submit.DistributedSparkSubmitter) NameMappedDatasetFramework(co.cask.cdap.internal.app.runtime.workflow.NameMappedDatasetFramework) DatasetFramework(co.cask.cdap.data2.dataset2.DatasetFramework) InstantiatorFactory(co.cask.cdap.common.lang.InstantiatorFactory) SparkSpecification(co.cask.cdap.api.spark.SparkSpecification) ProgramType(co.cask.cdap.proto.ProgramType) RunId(org.apache.twill.api.RunId) ProgramController(co.cask.cdap.app.runtime.ProgramController) Arguments(co.cask.cdap.app.runtime.Arguments) MessagingService(co.cask.cdap.messaging.MessagingService) MetricsCollectionService(co.cask.cdap.api.metrics.MetricsCollectionService) Service(com.google.common.util.concurrent.Service) ProgramId(co.cask.cdap.proto.id.ProgramId) BasicProgramContext(co.cask.cdap.internal.app.runtime.BasicProgramContext) LinkedList(java.util.LinkedList) IOException(java.io.IOException) WorkflowProgramInfo(co.cask.cdap.internal.app.runtime.workflow.WorkflowProgramInfo) PluginInstantiator(co.cask.cdap.internal.app.runtime.plugin.PluginInstantiator) Spark(co.cask.cdap.api.spark.Spark) LocalSparkSubmitter(co.cask.cdap.app.runtime.spark.submit.LocalSparkSubmitter) ProgramContextAware(co.cask.cdap.data.ProgramContextAware)

Aggregations

ProgramController (co.cask.cdap.app.runtime.ProgramController)37 ProgramId (co.cask.cdap.proto.id.ProgramId)13 IOException (java.io.IOException)10 Test (org.junit.Test)10 ProgramDescriptor (co.cask.cdap.app.program.ProgramDescriptor)9 ApplicationWithPrograms (co.cask.cdap.internal.app.deploy.pipeline.ApplicationWithPrograms)9 ProgramType (co.cask.cdap.proto.ProgramType)9 RunId (org.apache.twill.api.RunId)9 BasicArguments (co.cask.cdap.internal.app.runtime.BasicArguments)8 ApplicationSpecification (co.cask.cdap.api.app.ApplicationSpecification)7 AbstractListener (co.cask.cdap.internal.app.runtime.AbstractListener)7 NotFoundException (co.cask.cdap.common.NotFoundException)6 AbstractProgramController (co.cask.cdap.internal.app.runtime.AbstractProgramController)6 ExecutionException (java.util.concurrent.ExecutionException)6 ProgramOptions (co.cask.cdap.app.runtime.ProgramOptions)5 ArrayList (java.util.ArrayList)5 ProgramRuntimeService (co.cask.cdap.app.runtime.ProgramRuntimeService)4 BadRequestException (co.cask.cdap.common.BadRequestException)4 ConflictException (co.cask.cdap.common.ConflictException)4 NamespaceNotFoundException (co.cask.cdap.common.NamespaceNotFoundException)4