Search in sources :

Example 51 with Notification

use of io.cdap.cdap.proto.Notification in project cdap by cdapio.

the class ProgramNotificationSubscriberService method processWorkflowOnStop.

/**
 * On workflow program stop, inspects inner program states and adjust them if they are not in end state already.
 *
 * @param appMetadataStore the {@link AppMetadataStore} to write the status to
 * @param programHeartbeatTable the {@link ProgramHeartbeatTable} to write the status to
 * @param programRunId the program run of the completed program
 * @param programRunStatus the status of the completion
 * @param notification the {@link Notification} that carries information about the workflow completion
 * @param sourceId the source message id of the notification
 * @param runnables a {@link List} adding {@link Runnable} to be executed after event handling is completed
 * @throws Exception if failed to update program status
 */
private void processWorkflowOnStop(AppMetadataStore appMetadataStore, ProgramHeartbeatTable programHeartbeatTable, ProgramRunId programRunId, ProgramRunStatus programRunStatus, Notification notification, byte[] sourceId, List<Runnable> runnables) throws Exception {
    ApplicationId appId = programRunId.getParent().getParent();
    WorkflowSpecification workflowSpec = Optional.ofNullable(appMetadataStore.getApplication(appId)).map(appMeta -> appMeta.getSpec().getWorkflows().get(programRunId.getProgram())).orElse(null);
    // If cannot find the workflow spec (e.g. app deleted), then there is nothing we can do.
    if (workflowSpec == null) {
        return;
    }
    // For all MR and Spark nodes, we need to update the inner program run status if they are not in end state yet.
    for (WorkflowNode workflowNode : workflowSpec.getNodeIdMap().values()) {
        if (!(workflowNode instanceof WorkflowActionNode)) {
            continue;
        }
        ScheduleProgramInfo programInfo = ((WorkflowActionNode) workflowNode).getProgram();
        if (!WORKFLOW_INNER_PROGRAM_TYPES.containsKey(programInfo.getProgramType())) {
            continue;
        }
        // Get all active runs of the inner program. If the parent workflow runId is the same as this one,
        // set a terminal state for the inner program run.
        ProgramId innerProgramId = appId.program(WORKFLOW_INNER_PROGRAM_TYPES.get(programInfo.getProgramType()), programInfo.getProgramName());
        Map<ProgramRunId, Notification> innerProgramNotifications = new LinkedHashMap<>();
        appMetadataStore.scanActiveRuns(innerProgramId, runRecord -> {
            Map<String, String> systemArgs = runRecord.getSystemArgs();
            String workflowName = systemArgs.get(ProgramOptionConstants.WORKFLOW_NAME);
            String workflowRun = systemArgs.get(ProgramOptionConstants.WORKFLOW_RUN_ID);
            if (workflowName == null || workflowRun == null) {
                return;
            }
            ProgramRunId workflowRunId = appId.program(ProgramType.WORKFLOW, workflowName).run(workflowRun);
            if (!programRunId.equals(workflowRunId)) {
                return;
            }
            Map<String, String> notificationProps = new HashMap<>(notification.getProperties());
            notificationProps.put(ProgramOptionConstants.PROGRAM_RUN_ID, GSON.toJson(runRecord.getProgramRunId()));
            innerProgramNotifications.put(runRecord.getProgramRunId(), new Notification(Notification.Type.PROGRAM_STATUS, notificationProps));
        });
        for (Map.Entry<ProgramRunId, Notification> entry : innerProgramNotifications.entrySet()) {
            handleProgramEvent(entry.getKey(), programRunStatus, entry.getValue(), sourceId, appMetadataStore, programHeartbeatTable, runnables);
        }
    }
}
Also used : RunRecordDetail(io.cdap.cdap.internal.app.store.RunRecordDetail) ProvisionRequest(io.cdap.cdap.internal.provision.ProvisionRequest) ProvisionerNotifier(io.cdap.cdap.internal.provision.ProvisionerNotifier) TypeToken(com.google.gson.reflect.TypeToken) ImmutablePair(io.cdap.cdap.common.utils.ImmutablePair) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) Notification(io.cdap.cdap.proto.Notification) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) RetryStrategies(io.cdap.cdap.common.service.RetryStrategies) GsonBuilder(com.google.gson.GsonBuilder) WorkflowNode(io.cdap.cdap.api.workflow.WorkflowNode) ProgramStateWriter(io.cdap.cdap.app.runtime.ProgramStateWriter) SimpleProgramOptions(io.cdap.cdap.internal.app.runtime.SimpleProgramOptions) Gson(com.google.gson.Gson) Map(java.util.Map) BasicThrowable(io.cdap.cdap.proto.BasicThrowable) ImmutableMap(com.google.common.collect.ImmutableMap) MessagingService(io.cdap.cdap.messaging.MessagingService) Set(java.util.Set) ProgramRunStatus(io.cdap.cdap.proto.ProgramRunStatus) StructuredTableContext(io.cdap.cdap.spi.data.StructuredTableContext) SchedulableProgramType(io.cdap.cdap.api.schedule.SchedulableProgramType) StandardCharsets(java.nio.charset.StandardCharsets) ApplicationSpecificationAdapter(io.cdap.cdap.internal.app.ApplicationSpecificationAdapter) ScheduleProgramInfo(io.cdap.cdap.api.workflow.ScheduleProgramInfo) MetricsContext(io.cdap.cdap.api.metrics.MetricsContext) List(java.util.List) SecurityRequestContext(io.cdap.cdap.security.spi.authentication.SecurityRequestContext) Type(java.lang.reflect.Type) TransactionRunner(io.cdap.cdap.spi.data.transaction.TransactionRunner) Optional(java.util.Optional) Constants(io.cdap.cdap.common.conf.Constants) ProfileId(io.cdap.cdap.proto.id.ProfileId) Queue(java.util.Queue) ProgramOptionConstants(io.cdap.cdap.internal.app.runtime.ProgramOptionConstants) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) RunRecordDetailWithExistingStatus(io.cdap.cdap.internal.app.store.RunRecordDetailWithExistingStatus) ProgramRunners(io.cdap.cdap.internal.app.runtime.ProgramRunners) Retries(io.cdap.cdap.common.service.Retries) RetryStrategy(io.cdap.cdap.common.service.RetryStrategy) Cluster(io.cdap.cdap.runtime.spi.provisioner.Cluster) WorkflowSpecification(io.cdap.cdap.api.workflow.WorkflowSpecification) HashMap(java.util.HashMap) ProgramType(io.cdap.cdap.proto.ProgramType) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) ProvisioningService(io.cdap.cdap.internal.provision.ProvisioningService) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ProgramHeartbeatTable(io.cdap.cdap.reporting.ProgramHeartbeatTable) ProgramOptions(io.cdap.cdap.app.runtime.ProgramOptions) SystemArguments(io.cdap.cdap.internal.app.runtime.SystemArguments) WorkflowActionNode(io.cdap.cdap.api.workflow.WorkflowActionNode) LinkedList(java.util.LinkedList) Nullable(javax.annotation.Nullable) AppMetadataStore(io.cdap.cdap.internal.app.store.AppMetadataStore) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) JsonSyntaxException(com.google.gson.JsonSyntaxException) RunIds(io.cdap.cdap.common.app.RunIds) ProgramId(io.cdap.cdap.proto.id.ProgramId) ProgramDescriptor(io.cdap.cdap.app.program.ProgramDescriptor) IOException(java.io.IOException) ProjectInfo(io.cdap.cdap.common.utils.ProjectInfo) ProgramRunClusterStatus(io.cdap.cdap.proto.ProgramRunClusterStatus) TableNotFoundException(io.cdap.cdap.spi.data.TableNotFoundException) MetricsCollectionService(io.cdap.cdap.api.metrics.MetricsCollectionService) Store(io.cdap.cdap.app.store.Store) TimeUnit(java.util.concurrent.TimeUnit) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) Collections(java.util.Collections) BasicArguments(io.cdap.cdap.internal.app.runtime.BasicArguments) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) WorkflowActionNode(io.cdap.cdap.api.workflow.WorkflowActionNode) ProgramId(io.cdap.cdap.proto.id.ProgramId) WorkflowNode(io.cdap.cdap.api.workflow.WorkflowNode) Notification(io.cdap.cdap.proto.Notification) LinkedHashMap(java.util.LinkedHashMap) WorkflowSpecification(io.cdap.cdap.api.workflow.WorkflowSpecification) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ScheduleProgramInfo(io.cdap.cdap.api.workflow.ScheduleProgramInfo) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Example 52 with Notification

use of io.cdap.cdap.proto.Notification in project cdap by cdapio.

the class FileUploadServiceTestRun method testFileUploadService.

@Test
public void testFileUploadService() throws Exception {
    ApplicationManager appManager = deployApplication(FileUploadApp.class);
    // Start the service
    ServiceManager serviceManager = appManager.getServiceManager(FileUploadApp.SERVICE_NAME).start();
    serviceManager.waitForRun(ProgramRunStatus.RUNNING, 10, TimeUnit.SECONDS);
    try {
        // Upload URL is "base/upload/pfs/[partition_value], which the partition value is a long
        URI serviceURI = serviceManager.getServiceURL(10, TimeUnit.SECONDS).toURI();
        // Upload with wrong MD5, should get 400.
        byte[] content = Strings.repeat("0123456789 ", 100).getBytes(Charsets.UTF_8);
        Assert.assertEquals(HttpURLConnection.HTTP_BAD_REQUEST, upload(serviceURI.resolve("upload/" + FileUploadApp.PFS_NAME + "/1").toURL(), content, "123", 30));
        long beforeUploadTime = System.currentTimeMillis();
        // Upload with right MD5, should get 200
        Assert.assertEquals(HttpURLConnection.HTTP_OK, upload(serviceURI.resolve("upload/" + FileUploadApp.PFS_NAME + "/1").toURL(), content, Base64.getEncoder().encodeToString(Hashing.md5().hashBytes(content).asBytes()), 20));
        // Inspect the partitioned file set and verify the content
        PartitionedFileSet pfs = (PartitionedFileSet) getDataset(FileUploadApp.PFS_NAME).get();
        PartitionDetail partition = pfs.getPartition(PartitionKey.builder().addLongField("time", 1).build());
        Assert.assertNotNull(partition);
        // Verify a notification should have been published for the new partition
        List<Notification> notifications = getDataNotifications(beforeUploadTime);
        // Should have one message
        Assert.assertEquals(1, notifications.size());
        verifyDataNotification(notifications.get(0), NamespaceId.DEFAULT.dataset(FileUploadApp.PFS_NAME), Collections.singletonList(PartitionKey.builder().addLongField("time", 1L).build()));
        // There should be one file under the partition directory
        List<Location> locations = partition.getLocation().list();
        Assert.assertEquals(1, locations.size());
        Assert.assertArrayEquals(content, ByteStreams.toByteArray(Locations.newInputSupplier(locations.get(0))));
        // Verify the tracking table of chunks sizes
        KeyValueTable trackingTable = (KeyValueTable) getDataset(FileUploadApp.KV_TABLE_NAME).get();
        CloseableIterator<KeyValue<byte[], byte[]>> iter = trackingTable.scan(null, null);
        // Sum up all chunks sizes as being tracked by the tracking table.
        long sum = 0;
        int iterSize = 0;
        while (iter.hasNext()) {
            KeyValue<byte[], byte[]> kv = iter.next();
            sum += Bytes.toInt(kv.getKey()) * Bytes.toLong(kv.getValue());
            iterSize++;
        }
        // The iterator should have size >= 2, since we uses different chunk size for two different upload
        Assert.assertTrue(iterSize >= 2);
        // The sum of all chunks sizes should be the same as the
        // content size * 2 (since we have one failure, one success upload)
        Assert.assertEquals(content.length * 2, sum);
    } finally {
        serviceManager.stop();
        serviceManager.waitForRun(ProgramRunStatus.KILLED, 10, TimeUnit.SECONDS);
    }
}
Also used : ApplicationManager(io.cdap.cdap.test.ApplicationManager) KeyValue(io.cdap.cdap.api.dataset.lib.KeyValue) PartitionedFileSet(io.cdap.cdap.api.dataset.lib.PartitionedFileSet) PartitionDetail(io.cdap.cdap.api.dataset.lib.PartitionDetail) URI(java.net.URI) Notification(io.cdap.cdap.proto.Notification) ServiceManager(io.cdap.cdap.test.ServiceManager) KeyValueTable(io.cdap.cdap.api.dataset.lib.KeyValueTable) Location(org.apache.twill.filesystem.Location) Test(org.junit.Test)

Aggregations

Notification (io.cdap.cdap.proto.Notification)52 ProgramRunId (io.cdap.cdap.proto.id.ProgramRunId)14 IOException (java.io.IOException)14 Map (java.util.Map)14 Test (org.junit.Test)14 MessagingService (io.cdap.cdap.messaging.MessagingService)12 ProgramRunStatus (io.cdap.cdap.proto.ProgramRunStatus)12 Gson (com.google.gson.Gson)10 ProgramStateWriter (io.cdap.cdap.app.runtime.ProgramStateWriter)10 RunIds (io.cdap.cdap.common.app.RunIds)10 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)10 Constants (io.cdap.cdap.common.conf.Constants)10 MessagingProgramStateWriter (io.cdap.cdap.internal.app.program.MessagingProgramStateWriter)10 ProgramOptionConstants (io.cdap.cdap.internal.app.runtime.ProgramOptionConstants)10 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)10 ArrayList (java.util.ArrayList)10 Collections (java.util.Collections)10 List (java.util.List)10 TimeUnit (java.util.concurrent.TimeUnit)10 Nullable (javax.annotation.Nullable)10