Search in sources :

Example 1 with DeploymentTaskMetadata

use of com.aws.greengrass.deployment.model.DeploymentTaskMetadata in project aws-greengrass-nucleus by aws-greengrass.

the class IotJobsHelper method evaluateCancellationAndCancelDeploymentIfNeeded.

private void evaluateCancellationAndCancelDeploymentIfNeeded() {
    try {
        GreengrassService deploymentServiceLocateResult = kernel.locate(DeploymentService.DEPLOYMENT_SERVICE_TOPICS);
        if (deploymentServiceLocateResult instanceof DeploymentService) {
            DeploymentService deploymentService = (DeploymentService) deploymentServiceLocateResult;
            DeploymentTaskMetadata currentDeployment = deploymentService.getCurrentDeploymentTaskMetadata();
            // If the queue is not empty then it means deployment(s) from other sources is/are queued in it,
            // in that case don't add a cancellation deployment because it can't be added to the front of the queue
            // we will just have to let current deployment finish
            Deployment deployment = new Deployment(DeploymentType.IOT_JOBS, UUID.randomUUID().toString(), true);
            if (deploymentQueue.isEmpty() && currentDeployment != null && currentDeployment.isCancellable() && DeploymentType.IOT_JOBS.equals(currentDeployment.getDeploymentType()) && deploymentQueue.offer(deployment)) {
                logger.atInfo().log("Added cancellation deployment to the queue");
            }
        }
    } catch (ServiceLoadException e) {
        logger.atError().setCause(e).log("Failed to find deployment service");
    }
}
Also used : GreengrassService(com.aws.greengrass.lifecyclemanager.GreengrassService) Deployment(com.aws.greengrass.deployment.model.Deployment) DeploymentTaskMetadata(com.aws.greengrass.deployment.model.DeploymentTaskMetadata) ServiceLoadException(com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException)

Example 2 with DeploymentTaskMetadata

use of com.aws.greengrass.deployment.model.DeploymentTaskMetadata in project aws-greengrass-nucleus by aws-greengrass.

the class ShadowDeploymentListener method shadowUpdated.

protected void shadowUpdated(Map<String, Object> desired, Map<String, Object> reported, Integer version) {
    if (lastVersion.get() > version) {
        logger.atDebug().kv("SHADOW_VERSION", version).log("Received an older version of shadow. Ignoring...");
        return;
    }
    lastVersion.set(version);
    // the reported section of the shadow was updated
    if (reported != null && !reported.isEmpty()) {
        syncShadowDeploymentStatus(reported);
    }
    if (desired == null || desired.isEmpty()) {
        logger.debug("Empty desired state, no update to desired section or no device deployments created yet");
        return;
    }
    String fleetConfigStr = (String) desired.get(FLEET_CONFIG_KEY);
    Configuration configuration;
    try {
        configuration = SerializerFactory.getFailSafeJsonObjectMapper().readValue(fleetConfigStr, Configuration.class);
    } catch (JsonProcessingException e) {
        logger.atError().log("failed to process shadow update", e);
        return;
    }
    String configurationArn = configuration.getConfigurationArn();
    if (configurationArn == null) {
        logger.atError().log("Desired state has null configuration ARN. Ignoring shadow update");
        return;
    }
    String desiredStatus = (String) desired.get(DESIRED_STATUS_KEY);
    if (desiredStatus == null) {
        logger.atError().log("Desired status is null. Ignoring shadow update");
        return;
    }
    boolean cancelDeployment = DESIRED_STATUS_CANCELED.equals(desiredStatus);
    synchronized (ShadowDeploymentListener.class) {
        // If lastConfigurationArn is null, this is the first shadow update since startup
        if (lastConfigurationArn == null) {
            lastConfigurationArn = configurationArn;
            // Ignore if the latest deployment was canceled
            if (cancelDeployment) {
                logger.atInfo().kv(CONFIGURATION_ARN_LOG_KEY_NAME, configurationArn).log("Deployment was canceled. Ignoring shadow update at startup");
                return;
            }
            // the reported status is terminal (i.e. not in_progress) because it's already fully processed
            if (reported != null && configurationArn.equals(reported.get(ARN_FOR_STATUS_KEY)) && !JobStatus.IN_PROGRESS.toString().equals(reported.get(STATUS_KEY))) {
                logger.atInfo().kv(CONFIGURATION_ARN_LOG_KEY_NAME, configurationArn).log("Deployment result already reported. Ignoring shadow update at startup");
                return;
            }
            // Ignore if it's the ongoing deployment. This can happen if the last shadow deployment caused restart
            try {
                // Using locate instead of injection here because DeploymentService lacks usable injection
                // constructor. Same as in IotJobsHelper.evaluateCancellationAndCancelDeploymentIfNeeded
                GreengrassService deploymentServiceLocateResult = kernel.locate(DeploymentService.DEPLOYMENT_SERVICE_TOPICS);
                if (deploymentServiceLocateResult instanceof DeploymentService) {
                    DeploymentTaskMetadata currentDeployment = ((DeploymentService) deploymentServiceLocateResult).getCurrentDeploymentTaskMetadata();
                    if (currentDeployment != null && configurationArn.equals(currentDeployment.getDeploymentId())) {
                        logger.atInfo().kv(CONFIGURATION_ARN_LOG_KEY_NAME, configurationArn).log("Ongoing deployment. Ignoring shadow update at startup");
                        return;
                    }
                }
            } catch (ServiceLoadException e) {
                logger.atError().setCause(e).log("Failed to find deployment service");
            }
        } else {
            if (lastConfigurationArn.equals(configurationArn) && !cancelDeployment) {
                logger.atInfo().kv(CONFIGURATION_ARN_LOG_KEY_NAME, configurationArn).log("Duplicate deployment notification. Ignoring shadow update");
                return;
            }
            lastConfigurationArn = configurationArn;
        }
    }
    Deployment deployment;
    if (cancelDeployment) {
        deployment = new Deployment(DeploymentType.SHADOW, UUID.randomUUID().toString(), true);
    } else {
        deployment = new Deployment(fleetConfigStr, DeploymentType.SHADOW, configurationArn);
    }
    if (deploymentQueue.offer(deployment)) {
        logger.atInfo().kv("ID", deployment.getId()).log("Added shadow deployment job");
    }
}
Also used : Configuration(com.amazon.aws.iot.greengrass.configuration.common.Configuration) GreengrassService(com.aws.greengrass.lifecyclemanager.GreengrassService) Deployment(com.aws.greengrass.deployment.model.Deployment) DeploymentTaskMetadata(com.aws.greengrass.deployment.model.DeploymentTaskMetadata) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ServiceLoadException(com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException)

Example 3 with DeploymentTaskMetadata

use of com.aws.greengrass.deployment.model.DeploymentTaskMetadata in project aws-greengrass-nucleus by aws-greengrass.

the class IotJobsHelperTest method GIVEN_ongoing_job_deployment_WHEN_notification_with_empty_jobs_list_THEN_cancel_current_deployment.

@Test
void GIVEN_ongoing_job_deployment_WHEN_notification_with_empty_jobs_list_THEN_cancel_current_deployment() throws Exception {
    iotJobsHelper.postInject();
    iotJobsHelper.setDeploymentQueue(mockDeploymentQueue);
    when(mockDeploymentQueue.isEmpty()).thenReturn(true);
    CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.completedFuture(1);
    when(mockIotJobsClientWrapper.SubscribeToJobExecutionsChangedEvents(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    when(mockIotJobsClientWrapper.SubscribeToDescribeJobExecutionAccepted(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    when(mockIotJobsClientWrapper.SubscribeToDescribeJobExecutionRejected(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    DeploymentTaskMetadata mockCurrentDeploymentTaskMetadata = mock(DeploymentTaskMetadata.class);
    when(mockCurrentDeploymentTaskMetadata.getDeploymentType()).thenReturn(IOT_JOBS);
    when(mockCurrentDeploymentTaskMetadata.isCancellable()).thenReturn(true);
    when(mockDeploymentService.getCurrentDeploymentTaskMetadata()).thenReturn(mockCurrentDeploymentTaskMetadata);
    iotJobsHelper.subscribeToJobsTopics();
    verify(mockIotJobsClientWrapper, times(2)).SubscribeToJobExecutionsChangedEvents(any(), eq(QualityOfService.AT_LEAST_ONCE), eventChangeResponseCaptor.capture());
    JobExecutionsChangedEvent event = new JobExecutionsChangedEvent();
    event.jobs = new HashMap<>();
    eventChangeResponseCaptor.getValue().accept(event);
    verify(mockIotJobsClientWrapper, times(2)).PublishDescribeJobExecution(any(), eq(QualityOfService.AT_LEAST_ONCE));
    ArgumentCaptor<Deployment> deploymentArgumentCaptor = ArgumentCaptor.forClass(Deployment.class);
    verify(mockDeploymentQueue).offer(deploymentArgumentCaptor.capture());
    Deployment actualDeployment = deploymentArgumentCaptor.getValue();
    assertTrue(actualDeployment.isCancelled());
    assertEquals(IOT_JOBS, actualDeployment.getDeploymentType());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) JobExecutionsChangedEvent(software.amazon.awssdk.iot.iotjobs.model.JobExecutionsChangedEvent) Deployment(com.aws.greengrass.deployment.model.Deployment) DeploymentTaskMetadata(com.aws.greengrass.deployment.model.DeploymentTaskMetadata) Test(org.junit.jupiter.api.Test)

Example 4 with DeploymentTaskMetadata

use of com.aws.greengrass.deployment.model.DeploymentTaskMetadata in project aws-greengrass-nucleus by aws-greengrass.

the class IotJobsHelperTest method GIVEN_ongoing_job_deployment_with_queued_job_in_cloud_WHEN_cancel_notification_THEN_cancel_current_deployment.

@Test
void GIVEN_ongoing_job_deployment_with_queued_job_in_cloud_WHEN_cancel_notification_THEN_cancel_current_deployment() throws Exception {
    iotJobsHelper.postInject();
    String TEST_JOB_ID = "jobToBeCancelled";
    iotJobsHelper.setDeploymentQueue(mockDeploymentQueue);
    when(mockDeploymentQueue.isEmpty()).thenReturn(true);
    CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.completedFuture(1);
    when(mockIotJobsClientWrapper.SubscribeToJobExecutionsChangedEvents(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    when(mockIotJobsClientWrapper.SubscribeToDescribeJobExecutionAccepted(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    when(mockIotJobsClientWrapper.SubscribeToDescribeJobExecutionRejected(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    DeploymentTaskMetadata mockCurrentDeploymentTaskMetadata = mock(DeploymentTaskMetadata.class);
    when(mockCurrentDeploymentTaskMetadata.getDeploymentType()).thenReturn(IOT_JOBS);
    when(mockCurrentDeploymentTaskMetadata.isCancellable()).thenReturn(true);
    when(mockDeploymentService.getCurrentDeploymentTaskMetadata()).thenReturn(mockCurrentDeploymentTaskMetadata);
    iotJobsHelper.subscribeToJobsTopics();
    verify(mockIotJobsClientWrapper, times(2)).SubscribeToDescribeJobExecutionAccepted(any(), eq(QualityOfService.AT_LEAST_ONCE), describeJobResponseCaptor.capture());
    JobExecutionData jobExecutionData = new JobExecutionData();
    jobExecutionData.jobId = TEST_JOB_ID;
    jobExecutionData.status = JobStatus.QUEUED;
    jobExecutionData.queuedAt = new Timestamp(new Date());
    HashMap<String, Object> sampleJobDocument = new HashMap<>();
    sampleJobDocument.put("DeploymentId", TEST_JOB_ID);
    jobExecutionData.jobDocument = sampleJobDocument;
    DescribeJobExecutionResponse describeJobExecutionResponse = new DescribeJobExecutionResponse();
    describeJobExecutionResponse.execution = jobExecutionData;
    describeJobResponseCaptor.getValue().accept(describeJobExecutionResponse);
    ArgumentCaptor<Deployment> deploymentArgumentCaptor = ArgumentCaptor.forClass(Deployment.class);
    verify(mockDeploymentQueue, times(2)).offer(deploymentArgumentCaptor.capture());
    // First queued deployment should be for cancellation and then next one for next queued job
    List<Deployment> actualDeployments = deploymentArgumentCaptor.getAllValues();
    assertTrue(actualDeployments.get(0).isCancelled());
    assertEquals(IOT_JOBS, actualDeployments.get(0).getDeploymentType());
    assertFalse(actualDeployments.get(1).isCancelled());
    assertEquals(IOT_JOBS, actualDeployments.get(1).getDeploymentType());
    assertEquals(TEST_JOB_ID, actualDeployments.get(1).getId());
}
Also used : JobExecutionData(software.amazon.awssdk.iot.iotjobs.model.JobExecutionData) HashMap(java.util.HashMap) DescribeJobExecutionResponse(software.amazon.awssdk.iot.iotjobs.model.DescribeJobExecutionResponse) Deployment(com.aws.greengrass.deployment.model.Deployment) Timestamp(software.amazon.awssdk.iot.Timestamp) Date(java.util.Date) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DeploymentTaskMetadata(com.aws.greengrass.deployment.model.DeploymentTaskMetadata) Test(org.junit.jupiter.api.Test)

Example 5 with DeploymentTaskMetadata

use of com.aws.greengrass.deployment.model.DeploymentTaskMetadata in project aws-greengrass-nucleus by aws-greengrass.

the class IotJobsHelperTest method GIVEN_ongoing_local_deployment_WHEN_notification_with_empty_jobs_list_THEN_do_nothing.

@Test
void GIVEN_ongoing_local_deployment_WHEN_notification_with_empty_jobs_list_THEN_do_nothing() throws Exception {
    iotJobsHelper.postInject();
    iotJobsHelper.setDeploymentQueue(mockDeploymentQueue);
    when(mockDeploymentQueue.isEmpty()).thenReturn(true);
    CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.completedFuture(1);
    when(mockIotJobsClientWrapper.SubscribeToJobExecutionsChangedEvents(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    when(mockIotJobsClientWrapper.SubscribeToDescribeJobExecutionAccepted(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    when(mockIotJobsClientWrapper.SubscribeToDescribeJobExecutionRejected(any(), eq(QualityOfService.AT_LEAST_ONCE), any())).thenReturn(integerCompletableFuture);
    DeploymentTaskMetadata mockCurrentDeploymentTaskMetadata = mock(DeploymentTaskMetadata.class);
    when(mockCurrentDeploymentTaskMetadata.getDeploymentType()).thenReturn(LOCAL);
    when(mockCurrentDeploymentTaskMetadata.isCancellable()).thenReturn(true);
    when(mockDeploymentService.getCurrentDeploymentTaskMetadata()).thenReturn(mockCurrentDeploymentTaskMetadata);
    iotJobsHelper.subscribeToJobsTopics();
    verify(mockIotJobsClientWrapper, times(2)).SubscribeToJobExecutionsChangedEvents(any(), eq(QualityOfService.AT_LEAST_ONCE), eventChangeResponseCaptor.capture());
    JobExecutionsChangedEvent event = new JobExecutionsChangedEvent();
    event.jobs = new HashMap<>();
    eventChangeResponseCaptor.getValue().accept(event);
    verify(mockIotJobsClientWrapper, times(2)).PublishDescribeJobExecution(any(), eq(QualityOfService.AT_LEAST_ONCE));
    // Ongoing deployment is not of jobs type, it shouldn't be canceled, so nothing should be put in the queue
    verify(mockDeploymentQueue, times(0)).offer(any());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) JobExecutionsChangedEvent(software.amazon.awssdk.iot.iotjobs.model.JobExecutionsChangedEvent) DeploymentTaskMetadata(com.aws.greengrass.deployment.model.DeploymentTaskMetadata) Test(org.junit.jupiter.api.Test)

Aggregations

DeploymentTaskMetadata (com.aws.greengrass.deployment.model.DeploymentTaskMetadata)7 Deployment (com.aws.greengrass.deployment.model.Deployment)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 GreengrassService (com.aws.greengrass.lifecyclemanager.GreengrassService)3 Configuration (com.amazon.aws.iot.greengrass.configuration.common.Configuration)2 DeploymentResult (com.aws.greengrass.deployment.model.DeploymentResult)2 ServiceLoadException (com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException)2 Test (org.junit.jupiter.api.Test)2 ComponentRecipe (com.amazon.aws.iot.greengrass.component.common.ComponentRecipe)1 SerializerFactory.getRecipeSerializer (com.amazon.aws.iot.greengrass.component.common.SerializerFactory.getRecipeSerializer)1 SerializerFactory.getRecipeSerializerJson (com.amazon.aws.iot.greengrass.component.common.SerializerFactory.getRecipeSerializerJson)1 ComponentManager (com.aws.greengrass.componentmanager.ComponentManager)1 ComponentStore (com.aws.greengrass.componentmanager.ComponentStore)1 DependencyResolver (com.aws.greengrass.componentmanager.DependencyResolver)1 KernelConfigResolver (com.aws.greengrass.componentmanager.KernelConfigResolver)1 VERSION_CONFIG_KEY (com.aws.greengrass.componentmanager.KernelConfigResolver.VERSION_CONFIG_KEY)1 PackageLoadingException (com.aws.greengrass.componentmanager.exceptions.PackageLoadingException)1 ComponentIdentifier (com.aws.greengrass.componentmanager.models.ComponentIdentifier)1 Node (com.aws.greengrass.config.Node)1 PlatformResolver (com.aws.greengrass.config.PlatformResolver)1