Skip to content

Commit e974467

Browse files
committed
default finalizer naming correction, timer event source
1 parent 0467f07 commit e974467

File tree

2 files changed

+113
-20
lines changed

2 files changed

+113
-20
lines changed

operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ public class EventDispatcher {
2222
private final static Logger log = LoggerFactory.getLogger(EventDispatcher.class);
2323

2424
private final ResourceController controller;
25-
private final String resourceDefaultFinalizer;
25+
private final String resourceFinalizer;
2626
private final CustomResourceFacade customResourceFacade;
2727
private final boolean generationAware;
2828
private final Map<String, Long> lastGenerationProcessedSuccessfully = new ConcurrentHashMap<>();
2929

3030
public EventDispatcher(ResourceController controller,
31-
String defaultFinalizer,
31+
String finalizer,
3232
CustomResourceFacade customResourceFacade, boolean generationAware) {
3333
this.controller = controller;
3434
this.customResourceFacade = customResourceFacade;
35-
this.resourceDefaultFinalizer = defaultFinalizer;
35+
this.resourceFinalizer = finalizer;
3636
this.generationAware = generationAware;
3737
}
3838

@@ -53,8 +53,8 @@ private PostExecutionControl handDispatch(ExecutionScope executionScope) {
5353
cleanup(executionScope.getCustomResource());
5454
return PostExecutionControl.defaultDispatch();
5555
}
56-
if ((markedForDeletion(resource) && !ControllerUtils.hasGivenFinalizer(resource, resourceDefaultFinalizer))) {
57-
log.debug("Skipping event dispatching since its marked for deletion but has no default finalizer: {}", executionScope);
56+
if ((markedForDeletion(resource) && !ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer))) {
57+
log.debug("Skipping event dispatching since its marked for deletion but has no finalizer: {}", executionScope);
5858
return PostExecutionControl.defaultDispatch();
5959
}
6060
Context context = new DefaultContext(executionScope.getCustomResource(), executionScope.getEvents());
@@ -66,8 +66,8 @@ private PostExecutionControl handDispatch(ExecutionScope executionScope) {
6666
}
6767

6868
private PostExecutionControl handleCreateOrUpdate(ExecutionScope executionScope, CustomResource resource, Context context) {
69-
if (!ControllerUtils.hasGivenFinalizer(resource, resourceDefaultFinalizer) && !markedForDeletion(resource)) {
70-
/* We always add the default finalizer if missing and not marked for deletion.
69+
if (!ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer) && !markedForDeletion(resource)) {
70+
/* We always add the finalizer if missing and not marked for deletion.
7171
We execute the controller processing only for processing the event sent as a results
7272
of the finalizer add. This will make sure that the resources are not created before
7373
there is a finalizer.
@@ -101,13 +101,13 @@ private boolean skipBecauseOfGenerations(ExecutionScope executionScope) {
101101

102102
private PostExecutionControl handleDelete(CustomResource resource, Context context) {
103103
DeleteControl deleteControl = controller.deleteResource(resource, context);
104-
boolean hasDefaultFinalizer = ControllerUtils.hasGivenFinalizer(resource, resourceDefaultFinalizer);
105-
if (deleteControl.getRemoveFinalizer() && hasDefaultFinalizer) {
106-
removeDefaultFinalizer(resource);
104+
boolean hasFinalizer = ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer);
105+
if (deleteControl.getRemoveFinalizer() && hasFinalizer) {
106+
removeFinalizer(resource);
107107
cleanup(resource);
108108
} else {
109-
log.debug("Skipping finalizer remove. removeFinalizer: {}, hasDefaultFinalizer: {} ",
110-
deleteControl.getRemoveFinalizer(), hasDefaultFinalizer);
109+
log.debug("Skipping finalizer remove. removeFinalizer: {}, hasFinalizer: {} ",
110+
deleteControl.getRemoveFinalizer(), hasFinalizer);
111111
}
112112
return PostExecutionControl.defaultDispatch();
113113
}
@@ -148,9 +148,9 @@ private void updateCustomResource(CustomResource updatedResource) {
148148
}
149149

150150

151-
private void removeDefaultFinalizer(CustomResource resource) {
151+
private void removeFinalizer(CustomResource resource) {
152152
log.debug("Removing finalizer on resource {}:", resource);
153-
resource.getMetadata().getFinalizers().remove(resourceDefaultFinalizer);
153+
resource.getMetadata().getFinalizers().remove(resourceFinalizer);
154154
customResourceFacade.replaceWithLock(resource);
155155
}
156156

@@ -160,12 +160,12 @@ private void replace(CustomResource resource) {
160160
}
161161

162162
private void addFinalizerIfNotPresent(CustomResource resource) {
163-
if (!ControllerUtils.hasGivenFinalizer(resource, resourceDefaultFinalizer) && !markedForDeletion(resource)) {
164-
log.info("Adding default finalizer to {}", resource.getMetadata());
163+
if (!ControllerUtils.hasGivenFinalizer(resource, resourceFinalizer) && !markedForDeletion(resource)) {
164+
log.info("Adding finalizer to {}", resource.getMetadata());
165165
if (resource.getMetadata().getFinalizers() == null) {
166166
resource.getMetadata().setFinalizers(new ArrayList<>(1));
167167
}
168-
resource.getMetadata().getFinalizers().add(resourceDefaultFinalizer);
168+
resource.getMetadata().getFinalizers().add(resourceFinalizer);
169169
}
170170
}
171171

Original file line numberDiff line numberDiff line change
@@ -1,18 +1,111 @@
11
package io.javaoperatorsdk.operator.processing.event.internal;
22

33
import io.fabric8.kubernetes.client.CustomResource;
4+
import io.javaoperatorsdk.operator.processing.ProcessingUtils;
45
import io.javaoperatorsdk.operator.processing.event.AbstractEventSource;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
58

6-
import java.util.Timer;
9+
import java.util.*;
10+
import java.util.concurrent.ConcurrentHashMap;
11+
import java.util.concurrent.locks.ReentrantLock;
712

813
public class TimerEventSource extends AbstractEventSource {
914

15+
private Logger log = LoggerFactory.getLogger(TimerEventSource.class);
16+
1017
private final Timer timer = new Timer();
18+
private ReentrantLock lock = new ReentrantLock();
19+
20+
private Map<String, List<EvenProducerTimeTask>> timerTasks = new ConcurrentHashMap<>();
21+
22+
public void schedule(CustomResource customResource, long delay, long period) {
23+
String resourceUid = ProcessingUtils.getUID(customResource);
24+
EvenProducerTimeTask task = new EvenProducerTimeTask(resourceUid);
25+
storeTask(resourceUid, task);
26+
timer.schedule(task, delay, period);
27+
}
28+
29+
public void schedule(CustomResource customResource, long delay) {
30+
String resourceUid = ProcessingUtils.getUID(customResource);
31+
OneTimeEventProducerTimerTask task = new OneTimeEventProducerTimerTask(resourceUid);
32+
storeTask(resourceUid, task);
33+
timer.schedule(task, delay);
34+
}
35+
36+
private void storeTask(String resourceUid, EvenProducerTimeTask task) {
37+
try {
38+
lock.lock();
39+
List<EvenProducerTimeTask> tasks = getOrInitResourceRelatedTimers(resourceUid);
40+
tasks.add(task);
41+
} finally {
42+
lock.unlock();
43+
}
44+
}
45+
46+
private List<EvenProducerTimeTask> getOrInitResourceRelatedTimers(String resourceUid) {
47+
List<EvenProducerTimeTask> actualList = timerTasks.get(resourceUid);
48+
if (actualList == null) {
49+
actualList = new ArrayList<>();
50+
timerTasks.put(resourceUid, actualList);
51+
}
52+
return actualList;
53+
}
54+
55+
@Override
56+
public void eventSourceDeRegisteredForResource(String customResourceUid) {
57+
List<EvenProducerTimeTask> tasks = getEvenProducerTimeTask(customResourceUid);
58+
tasks.forEach(TimerTask::cancel);
59+
timerTasks.remove(customResourceUid);
60+
}
61+
62+
/**
63+
* This just to cover possible corner cases user might have
64+
*
65+
* @param customResourceUid
66+
* @return
67+
*/
68+
public List<EvenProducerTimeTask> getEvenProducerTimeTask(String customResourceUid) {
69+
List<EvenProducerTimeTask> tasks = timerTasks.get(customResourceUid);
70+
if (tasks == null) {
71+
return Collections.EMPTY_LIST;
72+
}
73+
return tasks;
74+
}
75+
76+
public class EvenProducerTimeTask extends TimerTask {
77+
protected final String customResourceUid;
1178

79+
public EvenProducerTimeTask(String customResourceUid) {
80+
this.customResourceUid = customResourceUid;
81+
}
1282

13-
public void schedule(CustomResource customResource ){
83+
@Override
84+
public void run() {
85+
log.debug("Producing event for custom resource id: {}", customResourceUid);
86+
eventHandler.handleEvent(new TimerEvent(customResourceUid, TimerEventSource.this));
87+
}
88+
}
1489

15-
};
90+
public class OneTimeEventProducerTimerTask extends EvenProducerTimeTask {
91+
public OneTimeEventProducerTimerTask(String customResourceUid) {
92+
super(customResourceUid);
93+
}
1694

95+
@Override
96+
public void run() {
97+
super.run();
98+
try {
99+
lock.lock();
100+
List<EvenProducerTimeTask> tasks = timerTasks.get(customResourceUid);
101+
tasks.remove(this);
102+
if (tasks.isEmpty()) {
103+
timerTasks.remove(customResourceUid);
104+
}
105+
} finally {
106+
lock.unlock();
107+
}
108+
}
109+
}
17110

18111
}

0 commit comments

Comments
 (0)