[[endpoint-roles]]
= Endpoint Roles

Starting with version 4.2, endpoints can be assigned to roles.
Roles let endpoints be started and stopped as a group.
This is particularly useful when using leadership election, where a set of endpoints can be started or stopped when leadership is granted or revoked, respectively.
For this purpose the framework registers a `SmartLifecycleRoleController` bean in the application context with the name `IntegrationContextUtils.INTEGRATION_LIFECYCLE_ROLE_CONTROLLER`.
Whenever it is necessary to control lifecycles, this bean can be injected or `@Autowired`:

[source, xml]
----
<bean class="com.some.project.SomeLifecycleControl">
    <property name="roleController" ref="integrationLifecycleRoleController"/>
</bean>
----

You can assign endpoints to roles using XML, Java configuration, or programmatically.
The following example shows how to configure endpoint roles with XML:

[source, xml]
----
<int:inbound-channel-adapter id="ica" channel="someChannel" expression="'foo'" role="cluster"
        auto-startup="false">
    <int:poller fixed-rate="60000" />
</int:inbound-channel-adapter>
----

The following example shows how to configure endpoint roles for a bean created in Java:

[source, java]
----
@Bean
@ServiceActivator(inputChannel = "sendAsyncChannel", autoStartup="false")
@Role("cluster")
public MessageHandler sendAsyncHandler() {
    return // some MessageHandler
}
----

The following example shows how to configure endpoint roles on a method in Java:

[source, java]
----
@Payload("#args[0].toLowerCase()")
@Role("cluster")
public String handle(String payload) {
    return payload.toUpperCase();
}
----

The following example shows how to configure endpoint roles by using the `SmartLifecycleRoleController` in Java:

[source, java]
----
@Autowired
private SmartLifecycleRoleController roleController;
...
    this.roleController.addSmartLifeCycleToRole("cluster", someEndpoint);
...
----

The following example shows how to configure endpoint roles by using an `IntegrationFlow` in Java:

[source, java]
----
IntegrationFlow flow -> flow
        .handle(..., e -> e.role("cluster"));
----

Each of these adds the endpoint to the `cluster` role.

Invoking `roleController.startLifecyclesInRole("cluster")` and the corresponding `stop...` method starts and stops the endpoints.

NOTE: Any object that implements `SmartLifecycle` can be programmatically added -- not just endpoints.

The `SmartLifecycleRoleController` implements `ApplicationListener<AbstractLeaderEvent>` and it automatically starts and stops its configured `SmartLifecycle` objects when leadership is granted or revoked (when some bean publishes `OnGrantedEvent` or `OnRevokedEvent`, respectively).

IMPORTANT: When using leadership election to start and stop components, it is important to set the `auto-startup` XML attribute (`autoStartup` bean property) to `false` so that the application context does not start the components during context initialization.

Starting with version 4.3.8, the `SmartLifecycleRoleController` provides several status methods:

[source, java]
----
public Collection<String> getRoles() <1>

public boolean allEndpointsRunning(String role) <2>

public boolean noEndpointsRunning(String role) <3>

public Map<String, Boolean> 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.