Search in sources :

Example 1 with GlobalStateChangeListener

use of com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener in project aws-greengrass-nucleus by aws-greengrass.

the class DeploymentConfigMergingTest method GIVEN_kernel_running_single_service_WHEN_merge_same_doc_happens_twice_THEN_second_merge_should_not_restart_services.

@Test
void GIVEN_kernel_running_single_service_WHEN_merge_same_doc_happens_twice_THEN_second_merge_should_not_restart_services() throws Throwable {
    // GIVEN
    ConfigPlatformResolver.initKernelWithMultiPlatformConfig(kernel, getClass().getResource("single_service.yaml"));
    // launch Nucleus
    CountDownLatch mainRunning = new CountDownLatch(1);
    kernel.getContext().addGlobalStateChangeListener((service, oldState, newState) -> {
        if (service.getName().equals("main") && newState.equals(State.RUNNING)) {
            mainRunning.countDown();
        }
    });
    kernel.launch();
    assertTrue(mainRunning.await(5, TimeUnit.SECONDS));
    Map<String, Object> nucleusConfig = getNucleusConfig();
    HashMap<String, Object> newConfig = new HashMap<String, Object>() {

        {
            put(SERVICES_NAMESPACE_TOPIC, new HashMap<String, Object>() {

                {
                    put("main", new HashMap<String, Object>() {

                        {
                            put(SERVICE_DEPENDENCIES_NAMESPACE_TOPIC, Arrays.asList("new_service", DEFAULT_NUCLEUS_COMPONENT_NAME));
                        }
                    });
                    put("new_service", new HashMap<String, Object>() {

                        {
                            put(SERVICE_LIFECYCLE_NAMESPACE_TOPIC, new HashMap<String, Object>() {

                                {
                                    put(LIFECYCLE_RUN_NAMESPACE_TOPIC, "echo done");
                                }
                            });
                            put(SERVICE_DEPENDENCIES_NAMESPACE_TOPIC, Arrays.asList("new_service2"));
                        }
                    });
                    put("new_service2", new HashMap<String, Object>() {

                        {
                            put(SERVICE_LIFECYCLE_NAMESPACE_TOPIC, new HashMap<String, Object>() {

                                {
                                    put(LIFECYCLE_RUN_NAMESPACE_TOPIC, "echo done");
                                }
                            });
                        }
                    });
                    put(DEFAULT_NUCLEUS_COMPONENT_NAME, nucleusConfig);
                }
            });
        }
    };
    // do first merge
    CountDownLatch mainRestarted = new CountDownLatch(1);
    AtomicBoolean newService2Started = new AtomicBoolean(false);
    AtomicBoolean newServiceStarted = new AtomicBoolean(false);
    GlobalStateChangeListener listener = (service, oldState, newState) -> {
        if (service.getName().equals("new_service2") && newState.equals(State.RUNNING)) {
            newService2Started.set(true);
        }
        if (newService2Started.get() && service.getName().equals("new_service") && newState.equals(State.RUNNING)) {
            newServiceStarted.set(true);
        }
        // Only count main as started if its dependency (new_service) has already been started
        if (newServiceStarted.get() && service.getName().equals("main") && newState.equals(State.FINISHED) && oldState.equals(State.STARTING)) {
            mainRestarted.countDown();
        }
    };
    kernel.getContext().addGlobalStateChangeListener(listener);
    GreengrassService main = kernel.locate("main");
    deploymentConfigMerger.mergeInNewConfig(testDeployment(), newConfig).get(60, TimeUnit.SECONDS);
    // Verify that first merge succeeded.
    assertTrue(newService2Started.get());
    assertTrue(newServiceStarted.get());
    assertTrue(mainRestarted.await(10, TimeUnit.SECONDS));
    assertThat(kernel.orderedDependencies().stream().map(GreengrassService::getName).collect(Collectors.toList()), containsInRelativeOrder("new_service2", "new_service", "main"));
    // Wait for main to finish before continuing, otherwise the state change listner may cause a failure
    assertThat(main::getState, eventuallyEval(is(State.FINISHED)));
    // WHEN
    AtomicBoolean stateChanged = new AtomicBoolean(false);
    listener = (service, oldState, newState) -> {
        System.err.println("State shouldn't change in merging the same config: " + service.getName() + " " + oldState + " => " + newState);
        stateChanged.set(true);
    };
    kernel.getContext().addGlobalStateChangeListener(listener);
    // THEN
    // merge in the same config the second time
    // merge shouldn't block
    deploymentConfigMerger.mergeInNewConfig(testDeployment(), newConfig).get(60, TimeUnit.SECONDS);
    // main should be finished
    assertEquals(State.FINISHED, main.getState());
    assertFalse(stateChanged.get(), "State shouldn't change in merging the same config.");
    // remove listener
    kernel.getContext().removeGlobalStateChangeListener(listener);
}
Also used : TestUtils.createCloseableLogListener(com.aws.greengrass.testcommons.testutilities.TestUtils.createCloseableLogListener) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) SocketOptions(software.amazon.awssdk.crt.io.SocketOptions) Deployment(com.aws.greengrass.deployment.model.Deployment) TimeoutException(java.util.concurrent.TimeoutException) Matchers.containsInRelativeOrder(org.hamcrest.Matchers.containsInRelativeOrder) ComponentUpdatePolicyEvents(software.amazon.awssdk.aws.greengrass.model.ComponentUpdatePolicyEvents) SubscribeToComponentUpdatesResponse(software.amazon.awssdk.aws.greengrass.model.SubscribeToComponentUpdatesResponse) AfterAll(org.junit.jupiter.api.AfterAll) DEFAULT_NUCLEUS_COMPONENT_NAME(com.aws.greengrass.deployment.DeviceConfiguration.DEFAULT_NUCLEUS_COMPONENT_NAME) IPCTestUtils(com.aws.greengrass.integrationtests.ipc.IPCTestUtils) Future(java.util.concurrent.Future) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) State(com.aws.greengrass.dependency.State) BaseITCase(com.aws.greengrass.integrationtests.BaseITCase) BeforeAll(org.junit.jupiter.api.BeforeAll) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) GenericExternalService(com.aws.greengrass.lifecyclemanager.GenericExternalService) FleetStatusService(com.aws.greengrass.status.FleetStatusService) DEFAULT(com.aws.greengrass.deployment.model.Deployment.DeploymentStage.DEFAULT) Duration(java.time.Duration) Map(java.util.Map) LogManager(com.aws.greengrass.logging.impl.LogManager) DeploymentDocument(com.aws.greengrass.deployment.model.DeploymentDocument) StreamResponseHandler(software.amazon.awssdk.eventstreamrpc.StreamResponseHandler) ComponentUpdatePolicy(com.aws.greengrass.deployment.model.ComponentUpdatePolicy) DeploymentResult(com.aws.greengrass.deployment.model.DeploymentResult) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) GreengrassCoreIPCClient(software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient) TestUtils(com.aws.greengrass.testcommons.testutilities.TestUtils) EventuallyLambdaMatcher.eventuallyEval(com.github.grantwest.eventually.EventuallyLambdaMatcher.eventuallyEval) Collectors(java.util.stream.Collectors) DeferComponentUpdateRequest(software.amazon.awssdk.aws.greengrass.model.DeferComponentUpdateRequest) TestUtils.createServiceStateChangeWaiter(com.aws.greengrass.testcommons.testutilities.TestUtils.createServiceStateChangeWaiter) Test(org.junit.jupiter.api.Test) Topics(com.aws.greengrass.config.Topics) Kernel(com.aws.greengrass.lifecyclemanager.Kernel) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) GlobalStateChangeListener(com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Optional(java.util.Optional) LIFECYCLE_RUN_NAMESPACE_TOPIC(com.aws.greengrass.lifecyclemanager.GenericExternalService.LIFECYCLE_RUN_NAMESPACE_TOPIC) Matchers.is(org.hamcrest.Matchers.is) DeploymentConfigMerger(com.aws.greengrass.deployment.DeploymentConfigMerger) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ConfigPlatformResolver(com.aws.greengrass.integrationtests.util.ConfigPlatformResolver) DeploymentConfigurationValidationPolicy(software.amazon.awssdk.services.greengrassv2.model.DeploymentConfigurationValidationPolicy) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Coerce(com.aws.greengrass.util.Coerce) SKIP_NOTIFY_COMPONENTS(software.amazon.awssdk.services.greengrassv2.model.DeploymentComponentUpdatePolicyAction.SKIP_NOTIFY_COMPONENTS) ArrayList(java.util.ArrayList) GreengrassService(com.aws.greengrass.lifecyclemanager.GreengrassService) SudoUtil.assumeCanSudoShell(com.aws.greengrass.testcommons.testutilities.SudoUtil.assumeCanSudoShell) GGExtension(com.aws.greengrass.testcommons.testutilities.GGExtension) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) PlatformResolver(com.aws.greengrass.config.PlatformResolver) ServiceLoadException(com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException) SystemUtils(org.apache.commons.lang3.SystemUtils) Matchers(org.hamcrest.Matchers) EventStreamRPCConnection(software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection) IOException(java.io.IOException) NOTIFY_COMPONENTS(software.amazon.awssdk.services.greengrassv2.model.DeploymentComponentUpdatePolicyAction.NOTIFY_COMPONENTS) SubscribeToComponentUpdatesRequest(software.amazon.awssdk.aws.greengrass.model.SubscribeToComponentUpdatesRequest) SUCCESSFUL(com.aws.greengrass.deployment.model.DeploymentResult.DeploymentStatus.SUCCESSFUL) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Topic(com.aws.greengrass.config.Topic) AfterEach(org.junit.jupiter.api.AfterEach) Matchers.hasItem(org.hamcrest.Matchers.hasItem) WhatHappened(com.aws.greengrass.config.WhatHappened) NoOpPathOwnershipHandler(com.aws.greengrass.testcommons.testutilities.NoOpPathOwnershipHandler) FailureHandlingPolicy(com.aws.greengrass.deployment.model.FailureHandlingPolicy) GreengrassLogMessage(com.aws.greengrass.logging.impl.GreengrassLogMessage) Logger(com.aws.greengrass.logging.api.Logger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) GreengrassService(com.aws.greengrass.lifecyclemanager.GreengrassService) HashMap(java.util.HashMap) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) GlobalStateChangeListener(com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test)

Example 2 with GlobalStateChangeListener

use of com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener in project aws-greengrass-cli by aws-greengrass.

the class IPCCliTest method GIVEN_kernel_running_WHEN_CLI_authorized_groups_updated_THEN_old_token_revoked_and_new_token_accepted.

@Test
@Order(10)
void GIVEN_kernel_running_WHEN_CLI_authorized_groups_updated_THEN_old_token_revoked_and_new_token_accepted(ExtensionContext context) throws Exception {
    ignoreExceptionOfType(context, RuntimeException.class);
    String oldAuthToken = getAuthTokenFromInfoFile();
    CountDownLatch awaitIpcServiceLatch = new CountDownLatch(1);
    GlobalStateChangeListener listener = getListenerForServiceRunning(awaitIpcServiceLatch, CLI_SERVICE);
    kernel.getContext().addGlobalStateChangeListener(listener);
    String validGid;
    if (PlatformResolver.isWindows) {
        // GG_NEEDS_REVIEW: TODO support windows
        validGid = "0";
    } else {
        validGid = selectAValidGid();
    }
    assertNotNull(validGid, "Failed to find a single valid GID on this test instance");
    kernel.locate(CLI_SERVICE).getConfig().lookup(CONFIGURATION_CONFIG_KEY, AUTHORIZED_POSIX_GROUPS).withValue(validGid);
    assertTrue(awaitIpcServiceLatch.await(10, TimeUnit.SECONDS));
    kernel.getContext().removeGlobalStateChangeListener(listener);
    ExecutionException executionException = assertThrows(ExecutionException.class, () -> IPCTestUtils.connectToGGCOverEventStreamIPC(TestUtils.getSocketOptionsForIPC(), oldAuthToken, kernel));
    assertEquals(AccessDeniedException.class, executionException.getCause().getClass());
    try (EventStreamRPCConnection eventStreamRPCConnection = IPCTestUtils.connectToGGCOverEventStreamIPC(TestUtils.getSocketOptionsForIPC(), getAuthTokenFromInfoFile(), kernel)) {
        GreengrassCoreIPCClient client = new GreengrassCoreIPCClient(eventStreamRPCConnection);
        ListComponentsResponse listComponentsResponse = client.listComponents(new ListComponentsRequest(), Optional.empty()).getResponse().get(DEFAULT_TIMEOUT_IN_SEC, TimeUnit.SECONDS);
        assertTrue(listComponentsResponse.getComponents().size() > 0);
    }
}
Also used : GreengrassCoreIPCClient(software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient) EventStreamRPCConnection(software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection) ListComponentsResponse(software.amazon.awssdk.aws.greengrass.model.ListComponentsResponse) GlobalStateChangeListener(com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener) CountDownLatch(java.util.concurrent.CountDownLatch) ExecutionException(java.util.concurrent.ExecutionException) ListComponentsRequest(software.amazon.awssdk.aws.greengrass.model.ListComponentsRequest) Order(org.junit.jupiter.api.Order) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) TestMethodOrder(org.junit.jupiter.api.TestMethodOrder) Test(org.junit.jupiter.api.Test)

Example 3 with GlobalStateChangeListener

use of com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener in project aws-greengrass-cli by aws-greengrass.

the class IPCCliTest method prepareKernelFromConfigFile.

public static Kernel prepareKernelFromConfigFile(String configFile, Class testClass, String... serviceNames) throws InterruptedException, IOException {
    Kernel kernel = new Kernel();
    NoOpPathOwnershipHandler.register(kernel);
    ConfigPlatformResolver.initKernelWithMultiPlatformConfig(kernel, testClass.getResource(configFile));
    CountDownLatch awaitIpcServiceLatch = new CountDownLatch(serviceNames.length);
    GlobalStateChangeListener listener = getListenerForServiceRunning(awaitIpcServiceLatch, serviceNames);
    kernel.getContext().addGlobalStateChangeListener(listener);
    kernel.launch();
    Assertions.assertTrue(awaitIpcServiceLatch.await(60L, TimeUnit.SECONDS));
    kernel.getContext().removeGlobalStateChangeListener(listener);
    return kernel;
}
Also used : GlobalStateChangeListener(com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener) CountDownLatch(java.util.concurrent.CountDownLatch) Kernel(com.aws.greengrass.lifecyclemanager.Kernel)

Example 4 with GlobalStateChangeListener

use of com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener in project aws-greengrass-nucleus by aws-greengrass.

the class IPCTestUtils method prepareKernelFromConfigFile.

public static Kernel prepareKernelFromConfigFile(String configFile, Class testClass, String... serviceNames) throws InterruptedException, IOException {
    Kernel kernel = new Kernel();
    NoOpPathOwnershipHandler.register(kernel);
    ConfigPlatformResolver.initKernelWithMultiPlatformConfig(kernel, testClass.getResource(configFile));
    // ensure awaitIpcServiceLatch starts
    CountDownLatch awaitIpcServiceLatch = new CountDownLatch(serviceNames.length);
    GlobalStateChangeListener listener = getListenerForServiceRunning(awaitIpcServiceLatch, serviceNames);
    kernel.getContext().addGlobalStateChangeListener(listener);
    kernel.launch();
    assertTrue(awaitIpcServiceLatch.await(10, TimeUnit.SECONDS));
    kernel.getContext().removeGlobalStateChangeListener(listener);
    return kernel;
}
Also used : GlobalStateChangeListener(com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener) CountDownLatch(java.util.concurrent.CountDownLatch) Kernel(com.aws.greengrass.lifecyclemanager.Kernel)

Example 5 with GlobalStateChangeListener

use of com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener in project aws-greengrass-nucleus by aws-greengrass.

the class ServiceDependencyLifecycleTest method testRoutine.

@SuppressWarnings({ "PMD.LooseCoupling", "PMD.CloseResource" })
private static void testRoutine(long timeoutSeconds, Kernel kernel, Crashable action, String actionName, LinkedList<ExpectedStateTransition> expectedStateTransitions, Set<ExpectedStateTransition> unexpectedStateTransitions) throws Throwable {
    Context context = kernel.getContext();
    CountDownLatch assertionLatch = new CountDownLatch(1);
    List<ExpectedStateTransition> unexpectedSeenInOrder = new LinkedList<>();
    GlobalStateChangeListener listener = (GreengrassService service, State oldState, State newState) -> {
        if (!expectedStateTransitions.isEmpty()) {
            ExpectedStateTransition expected = expectedStateTransitions.peek();
            if (service.getName().equals(expected.serviceName) && oldState.equals(expected.was) && newState.equals(expected.current)) {
                logger.atWarn().kv("expected", expected).log("Just saw expected state event for service");
                expectedStateTransitions.pollFirst();
            }
            if (expectedStateTransitions.isEmpty()) {
                assertionLatch.countDown();
            }
        }
        ExpectedStateTransition actual = new ExpectedStateTransition(service.getName(), oldState, newState);
        logger.atInfo().kv("actual", actual).log("Actual state event");
        if (unexpectedStateTransitions.contains(actual)) {
            unexpectedSeenInOrder.add(actual);
        }
    };
    context.addGlobalStateChangeListener(listener);
    action.run();
    assertionLatch.await(timeoutSeconds, TimeUnit.SECONDS);
    context.removeGlobalStateChangeListener(listener);
    if (!expectedStateTransitions.isEmpty()) {
        logger.atError().kv("expected", expectedStateTransitions).kv("action", actionName).log("Fail to see state events");
        fail("Didn't see all expected state transitions for " + actionName);
    }
    if (!unexpectedSeenInOrder.isEmpty()) {
        logger.atError().kv("unexpected", unexpectedSeenInOrder).kv("action", actionName).log("Saw unexpected state events");
        fail("Saw unexpected state transitions for " + actionName);
    }
    logger.atWarn().log("End of " + actionName);
}
Also used : Context(com.aws.greengrass.dependency.Context) ExpectedStateTransition(com.aws.greengrass.integrationtests.lifecyclemanager.KernelTest.ExpectedStateTransition) GreengrassService(com.aws.greengrass.lifecyclemanager.GreengrassService) State(com.aws.greengrass.dependency.State) GlobalStateChangeListener(com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener) CountDownLatch(java.util.concurrent.CountDownLatch) LinkedList(java.util.LinkedList)

Aggregations

GlobalStateChangeListener (com.aws.greengrass.lifecyclemanager.GlobalStateChangeListener)7 CountDownLatch (java.util.concurrent.CountDownLatch)7 State (com.aws.greengrass.dependency.State)4 GreengrassService (com.aws.greengrass.lifecyclemanager.GreengrassService)4 Kernel (com.aws.greengrass.lifecyclemanager.Kernel)4 Context (com.aws.greengrass.dependency.Context)2 DEFAULT_NUCLEUS_COMPONENT_NAME (com.aws.greengrass.deployment.DeviceConfiguration.DEFAULT_NUCLEUS_COMPONENT_NAME)2 ExpectedStateTransition (com.aws.greengrass.integrationtests.lifecyclemanager.KernelTest.ExpectedStateTransition)2 GreengrassLogMessage (com.aws.greengrass.logging.impl.GreengrassLogMessage)2 Matchers.containsInAnyOrder (org.hamcrest.Matchers.containsInAnyOrder)2 Test (org.junit.jupiter.api.Test)2 GreengrassCoreIPCClient (software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient)2 EventStreamRPCConnection (software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection)2 PlatformResolver (com.aws.greengrass.config.PlatformResolver)1 Topic (com.aws.greengrass.config.Topic)1 Topics (com.aws.greengrass.config.Topics)1 WhatHappened (com.aws.greengrass.config.WhatHappened)1 DeploymentConfigMerger (com.aws.greengrass.deployment.DeploymentConfigMerger)1 ComponentUpdatePolicy (com.aws.greengrass.deployment.model.ComponentUpdatePolicy)1 Deployment (com.aws.greengrass.deployment.model.Deployment)1