Skip to content

Commit 0c57424

Browse files
authored
Merge pull request #651 from yue9944882/refactor/integrate-controller-manager-and-informer-factory
Refactor: Follow-up of controller-builder utils
2 parents 6b5f6ce + 792360a commit 0c57424

File tree

14 files changed

+296
-233
lines changed

14 files changed

+296
-233
lines changed

examples/src/main/java/io/kubernetes/client/examples/ControllerExample.java

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,31 @@ public static void main(String[] args) throws IOException {
5353
// Use builder library to construct a default controller.
5454
Controller controller =
5555
ControllerBuilder.defaultBuilder(informerFactory)
56-
.watch(V1Node.class)
57-
.withWorkQueueKeyFunc(
58-
(V1Node node) -> new Request(node.getMetadata().getName())) // optional, default to
59-
// Controllers#defaultReflectiveKeyFunc
60-
.withOnAddFilter(
61-
(V1Node createdNode) ->
62-
createdNode
63-
.getMetadata()
64-
.getName()
65-
.startsWith("docker-")) // optional, set onAdd filter
66-
.withOnUpdateFilter(
67-
(V1Node oldNode, V1Node newNode) ->
68-
newNode
69-
.getMetadata()
70-
.getName()
71-
.startsWith("docker-")) // optional, set onUpdate filter
72-
.withOnDeleteFilter(
73-
(V1Node deletedNode, Boolean stateUnknown) ->
74-
deletedNode
75-
.getMetadata()
76-
.getName()
77-
.startsWith("docker-")) // optional, set onDelete filter
78-
.endWatch()
56+
.watch(
57+
(workQueue) ->
58+
ControllerBuilder.controllerWatchBuilder(V1Node.class, workQueue)
59+
.withWorkQueueKeyFunc(
60+
(V1Node node) ->
61+
new Request(node.getMetadata().getName())) // optional, default to
62+
.withOnAddFilter(
63+
(V1Node createdNode) ->
64+
createdNode
65+
.getMetadata()
66+
.getName()
67+
.startsWith("docker-")) // optional, set onAdd filter
68+
.withOnUpdateFilter(
69+
(V1Node oldNode, V1Node newNode) ->
70+
newNode
71+
.getMetadata()
72+
.getName()
73+
.startsWith("docker-")) // optional, set onUpdate filter
74+
.withOnDeleteFilter(
75+
(V1Node deletedNode, Boolean stateUnknown) ->
76+
deletedNode
77+
.getMetadata()
78+
.getName()
79+
.startsWith("docker-")) // optional, set onDelete filter
80+
.build())
7981
.withReconciler(nodeReconciler) // required, set the actual reconciler
8082
.withName("node-printing-controller") // optional, set name for controller
8183
.withWorkerCount(4) // optional, set worker thread count
@@ -86,7 +88,9 @@ public static void main(String[] args) throws IOException {
8688

8789
// Use builder library to manage one or multiple controllers.
8890
ControllerManager controllerManager =
89-
ControllerBuilder.controllerManagerBuilder().addController(controller).build();
91+
ControllerBuilder.controllerManagerBuilder(informerFactory)
92+
.addController(controller)
93+
.build();
9094

9195
LeaderElectingController leaderElectingController =
9296
new LeaderElectingController(

extended/src/main/java/io/kubernetes/client/extended/controller/ControllerManager.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
package io.kubernetes.client.extended.controller;
22

3+
import io.kubernetes.client.informer.SharedInformerFactory;
34
import java.util.concurrent.CountDownLatch;
45
import java.util.concurrent.ExecutorService;
56
import java.util.concurrent.Executors;
67
import org.slf4j.Logger;
78
import org.slf4j.LoggerFactory;
89

9-
/** The type Controller manager manages a set of controllers' lifecycle. */
10+
/**
11+
* The type Controller manager manages a set of controllers' lifecycle and also their informer
12+
* factory.
13+
*/
1014
public class ControllerManager implements Controller {
1115
private static final Logger log = LoggerFactory.getLogger(DefaultController.class);
1216
private Controller[] controllers;
1317
private ExecutorService controllerThreadPool;
18+
private SharedInformerFactory informerFactory;
1419

1520
/**
1621
* Instantiates a new Controller manager.
1722
*
1823
* @param controllers the controllers to be managed.
1924
*/
20-
public ControllerManager(Controller... controllers) {
25+
public ControllerManager(SharedInformerFactory factory, Controller... controllers) {
2126
this.controllers = controllers;
27+
this.informerFactory = factory;
2228
}
2329

2430
@Override
@@ -29,13 +35,15 @@ public void shutdown() {
2935
if (controllerThreadPool != null) {
3036
this.controllerThreadPool.shutdown();
3137
}
38+
this.informerFactory.stopAllRegisteredInformers();
3239
}
3340

3441
@Override
3542
public void run() {
3643
if (controllers.length == 0) {
3744
throw new RuntimeException("no controller registered in the manager..");
3845
}
46+
this.informerFactory.startAllRegisteredInformers();
3947
CountDownLatch latch = new CountDownLatch(controllers.length);
4048
this.controllerThreadPool = Executors.newFixedThreadPool(controllers.length);
4149
for (Controller controller : this.controllers) {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.kubernetes.client.extended.controller;
2+
3+
import io.kubernetes.client.informer.ResourceEventHandler;
4+
5+
/**
6+
* The interface Controller watch defines how a controller watches certain resources.
7+
*
8+
* @param <ApiType> the type parameter
9+
*/
10+
public interface ControllerWatch<ApiType> {
11+
/**
12+
* Gets the watching resource class.
13+
*
14+
* @return the resouce class
15+
*/
16+
Class<ApiType> getResourceClass();
17+
18+
/**
19+
* Gets the event handler on watch events from the resource.
20+
*
21+
* @return the resource event handler
22+
*/
23+
ResourceEventHandler<ApiType> getResourceEventHandler();
24+
}
Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
*
1313
* @param <ApiType> the type parameter
1414
*/
15-
public class WorkQueueResourceEventHandler<ApiType> implements ResourceEventHandler<ApiType> {
15+
public class DefaultControllerWatch<ApiType> implements ControllerWatch<ApiType> {
1616

1717
private final WorkQueue<Request> workQueue;
1818
private final Function<ApiType, Request> workKeyGenerator;
19+
20+
private Class<ApiType> apiTypeClass;
1921
private Predicate<ApiType> onAddFilterPredicate;
2022
private BiPredicate<ApiType, ApiType> onUpdateFilterPredicate;
2123
private BiPredicate<ApiType, Boolean> onDeleteFilterPredicate;
@@ -26,9 +28,12 @@ public class WorkQueueResourceEventHandler<ApiType> implements ResourceEventHand
2628
* @param workQueue the work queue
2729
* @param workKeyGenerator the work key generator
2830
*/
29-
public WorkQueueResourceEventHandler(
30-
WorkQueue<Request> workQueue, Function<ApiType, Request> workKeyGenerator) {
31+
public DefaultControllerWatch(
32+
Class<ApiType> apiTypeClass,
33+
WorkQueue<Request> workQueue,
34+
Function<ApiType, Request> workKeyGenerator) {
3135
this.workQueue = workQueue;
36+
this.apiTypeClass = apiTypeClass;
3237
this.workKeyGenerator = workKeyGenerator;
3338
}
3439

@@ -56,25 +61,39 @@ public void setOnDeleteFilterPredicate(BiPredicate<ApiType, Boolean> onDeleteFil
5661
this.onDeleteFilterPredicate = onDeleteFilterPredicate;
5762
}
5863

59-
@Override
60-
public void onAdd(ApiType obj) {
61-
if (onAddFilterPredicate == null || onAddFilterPredicate.test(obj)) {
62-
workQueue.add(workKeyGenerator.apply(obj));
63-
}
64+
public Class<ApiType> getApiTypeClass() {
65+
return apiTypeClass;
6466
}
6567

6668
@Override
67-
public void onUpdate(ApiType oldObj, ApiType newObj) {
68-
if (onUpdateFilterPredicate == null || onUpdateFilterPredicate.test(oldObj, newObj)) {
69-
workQueue.add(workKeyGenerator.apply(newObj));
70-
}
69+
public Class<ApiType> getResourceClass() {
70+
return this.apiTypeClass;
7171
}
7272

7373
@Override
74-
public void onDelete(ApiType obj, boolean deletedFinalStateUnknown) {
75-
if (onDeleteFilterPredicate == null
76-
|| onDeleteFilterPredicate.test(obj, deletedFinalStateUnknown)) {
77-
workQueue.add(workKeyGenerator.apply(obj));
78-
}
74+
public ResourceEventHandler<ApiType> getResourceEventHandler() {
75+
return new ResourceEventHandler<ApiType>() {
76+
@Override
77+
public void onAdd(ApiType obj) {
78+
if (onAddFilterPredicate == null || onAddFilterPredicate.test(obj)) {
79+
workQueue.add(workKeyGenerator.apply(obj));
80+
}
81+
}
82+
83+
@Override
84+
public void onUpdate(ApiType oldObj, ApiType newObj) {
85+
if (onUpdateFilterPredicate == null || onUpdateFilterPredicate.test(oldObj, newObj)) {
86+
workQueue.add(workKeyGenerator.apply(newObj));
87+
}
88+
}
89+
90+
@Override
91+
public void onDelete(ApiType obj, boolean deletedFinalStateUnknown) {
92+
if (onDeleteFilterPredicate == null
93+
|| onDeleteFilterPredicate.test(obj, deletedFinalStateUnknown)) {
94+
workQueue.add(workKeyGenerator.apply(obj));
95+
}
96+
}
97+
};
7998
}
8099
}

extended/src/main/java/io/kubernetes/client/extended/controller/builder/ControllerBuilder.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.kubernetes.client.extended.controller.builder;
22

3+
import io.kubernetes.client.extended.controller.reconciler.Request;
4+
import io.kubernetes.client.extended.workqueue.WorkQueue;
35
import io.kubernetes.client.informer.SharedInformerFactory;
46

57
/** The type Controller builder is the entry class of controller builders. */
@@ -19,9 +21,20 @@ public static DefaultControllerBuilder defaultBuilder(SharedInformerFactory fact
1921
/**
2022
* Controller manager builder is for building controller-manager .
2123
*
24+
* @param factory the informer factory
2225
* @return the controller mananger builder
2326
*/
24-
public static ControllerManangerBuilder controllerManagerBuilder() {
25-
return new ControllerManangerBuilder();
27+
public static ControllerManagerBuilder controllerManagerBuilder(SharedInformerFactory factory) {
28+
return new ControllerManagerBuilder(factory);
29+
}
30+
31+
/**
32+
* Controller watch builder is for building controller-watch.
33+
*
34+
* @return the controller watch builder
35+
*/
36+
public static <ApiType> ControllerWatchBuilder<ApiType> controllerWatchBuilder(
37+
Class<ApiType> apiTypeClass, WorkQueue<Request> workQueue) {
38+
return new ControllerWatchBuilder(apiTypeClass, workQueue);
2639
}
2740
}
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
import io.kubernetes.client.extended.controller.Controller;
44
import io.kubernetes.client.extended.controller.ControllerManager;
5+
import io.kubernetes.client.informer.SharedInformerFactory;
56
import java.util.ArrayList;
67
import java.util.List;
78

89
/** The type Controller mananger builder. */
9-
public class ControllerManangerBuilder {
10+
public class ControllerManagerBuilder {
11+
12+
private SharedInformerFactory informerFactory;
1013

1114
/** Instantiates a new Controller mananger builder. */
12-
ControllerManangerBuilder() {
15+
ControllerManagerBuilder(SharedInformerFactory factory) {
16+
this.informerFactory = factory;
1317
this.controllerList = new ArrayList<>();
1418
}
1519

@@ -21,7 +25,7 @@ public class ControllerManangerBuilder {
2125
* @param controller the controller
2226
* @return the controller mananger builder
2327
*/
24-
public ControllerManangerBuilder addController(Controller controller) {
28+
public ControllerManagerBuilder addController(Controller controller) {
2529
this.controllerList.add(controller);
2630
return this;
2731
}
@@ -32,6 +36,7 @@ public ControllerManangerBuilder addController(Controller controller) {
3236
* @return the controller manager
3337
*/
3438
public ControllerManager build() {
35-
return new ControllerManager(controllerList.stream().toArray(Controller[]::new));
39+
return new ControllerManager(
40+
informerFactory, controllerList.stream().toArray(Controller[]::new));
3641
}
3742
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package io.kubernetes.client.extended.controller.builder;
2+
3+
import io.kubernetes.client.extended.controller.Controllers;
4+
import io.kubernetes.client.extended.controller.DefaultControllerWatch;
5+
import io.kubernetes.client.extended.controller.reconciler.Request;
6+
import io.kubernetes.client.extended.workqueue.WorkQueue;
7+
import java.util.function.BiPredicate;
8+
import java.util.function.Function;
9+
import java.util.function.Predicate;
10+
11+
public class ControllerWatchBuilder<ApiType> {
12+
13+
private Function<ApiType, Request> workKeyGenerator;
14+
private WorkQueue<Request> workQueue;
15+
private Class<ApiType> apiTypeClass;
16+
17+
private Predicate<ApiType> onAddFilterPredicate;
18+
private BiPredicate<ApiType, ApiType> onUpdateFilterPredicate;
19+
private BiPredicate<ApiType, Boolean> onDeleteFilterPredicate;
20+
21+
ControllerWatchBuilder(Class<ApiType> apiTypeClass, WorkQueue<Request> workQueue) {
22+
this.apiTypeClass = apiTypeClass;
23+
this.workKeyGenerator = Controllers.defaultReflectiveKeyFunc();
24+
this.workQueue = workQueue;
25+
}
26+
27+
/**
28+
* Sets a filter for add notification.
29+
*
30+
* @param filter the filter
31+
* @return the controller builder . controller watch builder
32+
*/
33+
public ControllerWatchBuilder<ApiType> withOnAddFilter(Predicate<ApiType> filter) {
34+
this.onAddFilterPredicate = filter;
35+
return this;
36+
}
37+
38+
/**
39+
* Sets a filter for update notification.
40+
*
41+
* @param filter the filter
42+
* @return the controller builder . controller watch builder
43+
*/
44+
public ControllerWatchBuilder<ApiType> withOnUpdateFilter(BiPredicate<ApiType, ApiType> filter) {
45+
this.onUpdateFilterPredicate = filter;
46+
return this;
47+
}
48+
49+
/**
50+
* Sets a filter for delete notification.
51+
*
52+
* @param filter the filter
53+
* @return the controller builder . controller watch builder
54+
*/
55+
public ControllerWatchBuilder<ApiType> withOnDeleteFilter(BiPredicate<ApiType, Boolean> filter) {
56+
this.onDeleteFilterPredicate = filter;
57+
return this;
58+
}
59+
60+
/**
61+
* Overrides work-queue key-func for the watch.
62+
*
63+
* @param workKeyGenerator the work key generator
64+
* @return the controller builder . controller watch builder
65+
*/
66+
public ControllerWatchBuilder<ApiType> withWorkQueueKeyFunc(
67+
Function<ApiType, Request> workKeyGenerator) {
68+
this.workKeyGenerator = workKeyGenerator;
69+
return this;
70+
}
71+
72+
/**
73+
* End building controller-watch.
74+
*
75+
* @return the controller builder
76+
* @throws IllegalStateException the illegal state exception
77+
*/
78+
public DefaultControllerWatch<ApiType> build() throws IllegalStateException {
79+
DefaultControllerWatch<ApiType> workQueueHandler =
80+
new DefaultControllerWatch<>(apiTypeClass, workQueue, workKeyGenerator);
81+
workQueueHandler.setOnAddFilterPredicate(onAddFilterPredicate);
82+
workQueueHandler.setOnUpdateFilterPredicate(onUpdateFilterPredicate);
83+
workQueueHandler.setOnDeleteFilterPredicate(onDeleteFilterPredicate);
84+
return workQueueHandler;
85+
}
86+
}

0 commit comments

Comments
 (0)