diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/README.md b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/README.md
new file mode 100644
index 00000000..1858ee66
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/README.md
@@ -0,0 +1,83 @@
+# Spring Cloud Kubernetes leader election example
+
+## Setting up the Environment
+
+This example uses a Fabric8 Maven Plugin to deploy an application to a Kubernetes cluster.
+To try it locally, download and install `[Minikube](https://kubernetes.io/docs/getting-started-guides/minikube/)`.
+
+Once Minikube is downloaded, start it with the following command:
+```
+minikube start
+```
+
+And configure environment variables to point to the Minikube's Docker daemon:
+```
+eval $(minikube docker-env)
+```
+
+## Overview
+
+Spring Cloud Kubernetes leader election mechanism implements leader election API of Spring Integration using Kubernetes ConfigMap.
+Multiple instances of the same application compete for a leadership of a specified role.
+But only one of them can become a leader and receive an `OnGrantedEvent` application event with a leadership `Context`.
+All the instances periodically try to get a leadership and whichever comes first - becomes a leader.
+The new leader will remain until either its instance disappears from the cluster or it yields its leadership.
+Once the leader is gone, any of the existing instances can become a new leader (even the previous leader if it yielded leadership but stayed in the cluster).
+And finally, if the leadership is yielded or revoked for some reason, the old leader receives `OnRevokedEvent` application event.
+
+## Example application usage
+
+To begin with, build and deploy the application:
+```
+mvn clean package fabric8:deploy -Pkubernetes
+```
+
+This will deploy a single application instance to the cluster and that instance will automatically become a leader.
+
+Create an environment variable for an easier application access:
+```
+SERVICE_URL=$(minikube service kubernetes-leader-election-example --url)
+```
+
+Get leadership information:
+```
+curl $SERVICE_URL
+```
+
+You should receive a message like this:
+```
+I am 'kubernetes-leader-election-example-1234567890-abcde' and I am the leader of the 'world'
+```
+
+Yield the leadership:
+```
+curl -X PUT $SERVICE_URL
+```
+
+And check the leadership information again:
+```
+curl $SERVICE_URL
+```
+
+Now you should receive a message like this:
+```
+I am 'kubernetes-leader-election-example-1234567890-abcde' but I am not a leader of the 'world'
+```
+
+If you wouldn't do anything for a few seconds, the same instance will become a leader again because it only yielded its leadership but stayed in the cluster.
+
+Now scale the application to two instances and try all the steps again:
+```
+kubectl scale --replicas=2 deployment.apps/kubernetes-leader-election-example
+```
+
+> Note: with multiple replicas in the cluster, `curl` command will access one of them depending on the Kubernetes load balancing configuration.
+Thus, when trying to yield the leadership, request might go to a non-leader node first. Just execute command again until it reaches the correct node.
+
+> Note: instances periodically try to acquire leadership and Spring Cloud Kubernetes doesn't decide which one of them is more worth to become one.
+Thus, it is possible that the instance which just yielded the leadership, made another leadership take over request faster than another instances and became a leader again.
+
+## Access control notice
+
+Leader election mechanism uses Kubernetes ConfigMap feature to coordinate leadership information.
+In order to access it, [Role](./src/main/fabric8/role.yaml) and [RoleBinding](./src/main/fabric8/rb.yaml) objects are defined.
diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml
new file mode 100644
index 00000000..7d6efb8d
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml
@@ -0,0 +1,110 @@
+
+
+ 4.0.0
+
+ org.springframework.cloud
+ spring-cloud-kubernetes-examples
+ 0.3.0.BUILD-SNAPSHOT
+
+
+ kubernetes-leader-election-example
+ Spring Cloud Kubernetes :: Examples :: Leader Election
+ Leader election demonstration with Spring Integration and ConfigMap
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ pom
+ import
+ ${spring-boot.version}
+
+
+ org.springframework.cloud
+ spring-cloud-kubernetes-leader
+ ${project.version}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.cloud
+ spring-cloud-kubernetes-leader
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${fabric8.maven.plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ ${maven-deploy-plugin.version}
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+
+
+ kubernetes
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+
+
+ fmp
+
+ resource
+ build
+
+
+
+
+
+
+
+ NodePort
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/rb.yaml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/rb.yaml
new file mode 100644
index 00000000..3aa75746
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/rb.yaml
@@ -0,0 +1,13 @@
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: RoleBinding
+metadata:
+ name: leader
+ namespace: default
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: leader
+subjects:
+- kind: ServiceAccount
+ name: default
+ namespace: default
diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/role.yaml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/role.yaml
new file mode 100644
index 00000000..988a9f00
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/role.yaml
@@ -0,0 +1,12 @@
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: Role
+metadata:
+ name: leader
+ namespace: default
+rules:
+- apiGroups:
+ resources:
+ - pods
+ - configmaps
+ verbs:
+ - "*"
diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
new file mode 100644
index 00000000..87a1c733
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 to the original authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.examples;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App {
+
+ public static void main(String[] args) {
+ SpringApplication.run(App.class, args);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/LeaderController.java b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/LeaderController.java
new file mode 100644
index 00000000..d8943d8b
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/LeaderController.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2018 to the original authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.examples;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.event.EventListener;
+import org.springframework.http.ResponseEntity;
+import org.springframework.integration.leader.Context;
+import org.springframework.integration.leader.event.OnGrantedEvent;
+import org.springframework.integration.leader.event.OnRevokedEvent;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class LeaderController {
+
+ private final String host;
+
+ @Value("${spring.cloud.kubernetes.leader.role}")
+ private String role;
+
+ private Context context;
+
+ public LeaderController() throws UnknownHostException {
+ this.host = InetAddress.getLocalHost().getHostName();
+ }
+
+ /**
+ * Return a message whether this instance is a leader or not.
+ *
+ * @return
+ */
+ @GetMapping
+ public String getInfo() {
+ if (context == null) {
+ return String.format("I am '%s' but I am not a leader of the '%s'", host, role);
+ }
+
+ return String.format("I am '%s' and I am the leader of the '%s'", host, role);
+ }
+
+ /**
+ * PUT request to try and revoke a leadership of this instance.
+ * If the instance is not a leader, leadership cannot be revoked. Thus "HTTP Bad Request" response.
+ * If the instance is a leader, it must have a leadership context instance which can be used to give up the
+ * leadership.
+ *
+ * @return
+ */
+ @PutMapping
+ public ResponseEntity revokeLeadership() {
+ if (context == null) {
+ String message = String.format("Cannot revoke leadership because '%s' is not a leader", host);
+ return ResponseEntity
+ .badRequest()
+ .body(message);
+ }
+
+ context.yield();
+
+ String message = String.format("Leadership revoked for '%s'", host);
+ return ResponseEntity
+ .ok(message);
+ }
+
+ /**
+ * Handle a notification that this instance has become a leader.
+ *
+ * @param event
+ */
+ @EventListener
+ public void handleEvent(OnGrantedEvent event) {
+ System.out.println(String.format("'%s' leadership granted", event.getRole()));
+ context = event.getContext();
+ }
+
+ /**
+ * Handle a notification that this instance's leadership has been revoked.
+ *
+ * @param event
+ */
+ @EventListener
+ public void handleEvent(OnRevokedEvent event) {
+ System.out.println(String.format("'%s' leadership revoked", event.getRole()));
+ context = null;
+ }
+}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/resources/application.properties b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/resources/application.properties
new file mode 100644
index 00000000..f6ededa7
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+# Role to which leader election this instance will participate
+spring.cloud.kubernetes.leader.role=world
diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java
new file mode 100644
index 00000000..7ce0ebc7
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java
@@ -0,0 +1,94 @@
+package org.springframework.cloud.kubernetes.examples;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.integration.leader.Context;
+import org.springframework.integration.leader.event.OnGrantedEvent;
+import org.springframework.integration.leader.event.OnRevokedEvent;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LeaderControllerTest {
+
+ @Mock
+ private OnGrantedEvent mockOnGrantedEvent;
+
+ @Mock
+ private OnRevokedEvent mockOnRevokedEvent;
+
+ @Mock
+ private Context mockContext;
+
+ private String host;
+
+ private LeaderController leaderController;
+
+ @Before
+ public void before() throws UnknownHostException {
+ host = InetAddress.getLocalHost().getHostName();
+ leaderController = new LeaderController();
+ }
+
+ @Test
+ public void shouldGetNonLeaderInfo() {
+ String message = String.format("I am '%s' but I am not a leader of the 'null'", host);
+ assertThat(leaderController.getInfo()).isEqualTo(message);
+ }
+
+ @Test
+ public void shouldHandleGrantedEvent() {
+ given(mockOnGrantedEvent.getContext()).willReturn(mockContext);
+
+ leaderController.handleEvent(mockOnGrantedEvent);
+
+ String message = String.format("I am '%s' and I am the leader of the 'null'", host);
+ assertThat(leaderController.getInfo()).isEqualTo(message);
+ }
+
+ @Test
+ public void shouldHandleRevokedEvent() {
+ given(mockOnGrantedEvent.getContext()).willReturn(mockContext);
+
+ leaderController.handleEvent(mockOnGrantedEvent);
+ leaderController.handleEvent(mockOnRevokedEvent);
+
+ String message = String.format("I am '%s' but I am not a leader of the 'null'", host);
+ assertThat(leaderController.getInfo()).isEqualTo(message);
+ }
+
+ @Test
+ public void shouldRevokeLeadership() {
+ given(mockOnGrantedEvent.getContext()).willReturn(mockContext);
+
+ leaderController.handleEvent(mockOnGrantedEvent);
+ ResponseEntity responseEntity = leaderController.revokeLeadership();
+
+ String message = String.format("Leadership revoked for '%s'", host);
+ assertThat(responseEntity.getBody()).isEqualTo(message);
+ assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
+ verify(mockContext).yield();
+ }
+
+ @Test
+ public void shouldNotRevokeLeadershipIfNotLeader() {
+ ResponseEntity responseEntity = leaderController.revokeLeadership();
+
+ String message = String.format("Cannot revoke leadership because '%s' is not a leader", host);
+ assertThat(responseEntity.getBody()).isEqualTo(message);
+ assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
+ verify(mockContext, times(0)).yield();
+ }
+
+}
diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml
index 73f0d60e..5b674e25 100644
--- a/spring-cloud-kubernetes-examples/pom.xml
+++ b/spring-cloud-kubernetes-examples/pom.xml
@@ -35,6 +35,7 @@
kubernetes-reload-example
kubernetes-hello-world-example
+ kubernetes-leader-election-example