From 006f7cfd6694c02bd9093e20d258764a28742d96 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Thu, 23 Feb 2017 13:24:23 -0500 Subject: [PATCH] INT-4236: Status for SmartLifecycleRoleControlller JIRA: https://jira.spring.io/browse/INT-4236 Add methods to obtain status from the `SmartLifecycleRoleController`. * Polishing according PR comments. * Fix log messages in the `SmartLifecycleRoleController` from the Zookeeper mentioning Conflicts: src/reference/asciidoc/endpoint.adoc Resolved. Also Java 6 Compatibility. --- .../support/SmartLifecycleRoleController.java | 95 +++++++++++++++++-- .../configuration/EnableIntegrationTests.java | 17 ++++ src/reference/asciidoc/endpoint.adoc | 23 +++++ src/reference/asciidoc/whats-new.adoc | 5 + 4 files changed, 133 insertions(+), 7 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/support/SmartLifecycleRoleController.java b/spring-integration-core/src/main/java/org/springframework/integration/support/SmartLifecycleRoleController.java index 28c3f73a18..66cde01bdc 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/support/SmartLifecycleRoleController.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/support/SmartLifecycleRoleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,13 @@ package org.springframework.integration.support; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.apache.commons.logging.Log; @@ -35,6 +38,7 @@ import org.springframework.context.SmartLifecycle; import org.springframework.integration.leader.event.AbstractLeaderEvent; import org.springframework.integration.leader.event.OnGrantedEvent; import org.springframework.integration.leader.event.OnRevokedEvent; +import org.springframework.integration.support.context.NamedComponent; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -43,6 +47,8 @@ import org.springframework.util.MultiValueMap; * Bulk start/stop {@link SmartLifecycle} in a particular role in phase order. * * @author Gary Russell + * @author Artem Bilan + * * @since 4.2 * */ @@ -143,7 +149,7 @@ public class SmartLifecycleRoleController implements ApplicationListener getRoles() { + if (this.lazyLifecycles.size() > 0) { + addLazyLifecycles(); + } + return new ArrayList(this.lifecycles.keySet()); + } + + /** + * Return true if all endpoints in the role are running. + * @param role the role. + * @return true if at least one endpoint in the role, and all are running. + * @since 4.3.8 + */ + public boolean allEndpointsRunning(String role) { + Map status = getEndpointsRunningStatus(role); + if (status.isEmpty()) { + return false; + } + else { + for (Boolean isRunning : status.values()) { + if (!isRunning) { + return false; + } + } + return true; + } + } + + /** + * Return true if none of the endpoints in the role are running or if + * there are no endpoints in the role. + * @param role the role. + * @return true if there are no endpoints or none are running. + * @since 4.3.8 + */ + public boolean noEndpointsRunning(String role) { + Map status = getEndpointsRunningStatus(role); + for (Boolean isRunning : status.values()) { + if (isRunning) { + return false; + } + } + return true; + } + + /** + * Return the running status of each endpoint in the role. + * @param role the role. + * @return A map of component names : running status + * @since 4.3.8 + */ + public Map getEndpointsRunningStatus(String role) { + if (this.lazyLifecycles.size() > 0) { + addLazyLifecycles(); + } + List endpoints = this.lifecycles.get(role); + if (endpoints == null || endpoints.isEmpty()) { + return Collections.emptyMap(); + } + int index = 0; + Map runners = new HashMap(); + for (SmartLifecycle lifecycle : endpoints) { + runners.put(lifecycle instanceof NamedComponent + ? ((NamedComponent) lifecycle).getComponentName() + : (lifecycle.getClass().getSimpleName() + "#" + index++), + lifecycle.isRunning()); + } + return runners; + } + + private synchronized void addLazyLifecycles() { for (Entry> entry : this.lazyLifecycles.entrySet()) { doAddLifecyclesToRole(entry.getKey(), entry.getValue()); } @@ -214,7 +295,7 @@ public class SmartLifecycleRoleController implements ApplicationListener state = this.roleController.getEndpointsRunningStatus("foo"); + assertThat(state.get("annotationTestService.handle.serviceActivator"), equalTo(Boolean.FALSE)); + assertThat(state.get("enableIntegrationTests.ContextConfiguration2.sendAsyncHandler.serviceActivator"), + equalTo(Boolean.TRUE)); + this.roleController.startLifecyclesInRole("foo"); + assertTrue(this.roleController.allEndpointsRunning("foo")); this.roleController.stopLifecyclesInRole("foo"); + assertFalse(this.roleController.allEndpointsRunning("foo")); + assertTrue(this.roleController.noEndpointsRunning("foo")); + @SuppressWarnings("unchecked") MultiValueMap lifecycles = TestUtils.getPropertyValue(this.roleController, "lifecycles", MultiValueMap.class); diff --git a/src/reference/asciidoc/endpoint.adoc b/src/reference/asciidoc/endpoint.adoc index 43dfd83b4f..b3715f6163 100644 --- a/src/reference/asciidoc/endpoint.adoc +++ b/src/reference/asciidoc/endpoint.adoc @@ -630,6 +630,29 @@ The `SmartLifecycleRoleController` implements `ApplicationListener getRoles() <1> + +public boolean allEndpointsRunning(String role) <2> + +public boolean noEndpointsRunning(String role) <3> + +public Map getEndpointsRunningStatus(String role) <4> +---- + +<1> Returns a list of the roles being managed. + +<2> Returns true if all endpoints in the role are running. + +<3> Returns true if none of the endpoints in the role are running. + +<4> Returns a map of `component name : running status` - the component name is usually the bean name. + [[leadership-event-handling]] === Leadership Event Handling diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc index 21997671e4..7e87d31128 100644 --- a/src/reference/asciidoc/whats-new.adoc +++ b/src/reference/asciidoc/whats-new.adoc @@ -79,6 +79,11 @@ To restore the previous behaviour specify the `spring.integration.messagingAnnot `spring.integration.properties` as `true`. See <> and <> for more information. +===== Lifecycle Role Controller + +The `SmartLifecycleRoleController` now provides methods to obtain status of endpoints in roles. +See <> for more information. + ==== Mail Changes ===== Customizable User Flag