Skip to content

Commit 1bf3522

Browse files
committed
feat: external state management for dependent resources
1 parent 7bd5735 commit 1bf3522

File tree

6 files changed

+92
-22
lines changed

6 files changed

+92
-22
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,38 +110,38 @@ private void logForOperation(String operation, P primary, R desired) {
110110
}
111111

112112
protected R handleCreate(R desired, P primary, Context<P> context) {
113-
ResourceID resourceID = ResourceID.fromResource(primary);
114113
R created = creator.create(desired, primary, context);
115114
throwIfNull(created, primary, "Created resource");
116-
onCreated(resourceID, created);
115+
onCreated(primary, created, context);
117116
return created;
118117
}
119118

120119
/**
121120
* Allows subclasses to perform additional processing (e.g. caching) on the created resource if
122121
* needed.
123122
*
124-
* @param primaryResourceId the {@link ResourceID} of the primary resource associated with the
125-
* newly created resource
123+
* @param primary the {@link ResourceID} of the primary resource associated with the newly created
124+
* resource
126125
* @param created the newly created resource
126+
* @param context
127127
*/
128-
protected abstract void onCreated(ResourceID primaryResourceId, R created);
128+
protected abstract void onCreated(P primary, R created, Context<P> context);
129129

130130
/**
131131
* Allows subclasses to perform additional processing on the updated resource if needed.
132132
*
133-
* @param primaryResourceId the {@link ResourceID} of the primary resource associated with the
134-
* newly updated resource
133+
* @param primary the {@link ResourceID} of the primary resource associated with the newly updated
134+
* resource
135135
* @param updated the updated resource
136136
* @param actual the resource as it was before the update
137+
* @param context
137138
*/
138-
protected abstract void onUpdated(ResourceID primaryResourceId, R updated, R actual);
139+
protected abstract void onUpdated(P primary, R updated, R actual, Context<P> context);
139140

140141
protected R handleUpdate(R actual, R desired, P primary, Context<P> context) {
141-
ResourceID resourceID = ResourceID.fromResource(primary);
142142
R updated = updater.update(actual, desired, primary, context);
143143
throwIfNull(updated, primary, "Updated resource");
144-
onUpdated(resourceID, updated, actual);
144+
onUpdated(primary, updated, actual, context);
145145
return updated;
146146
}
147147

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Optional;
44

55
import io.fabric8.kubernetes.api.model.HasMetadata;
6+
import io.javaoperatorsdk.operator.api.reconciler.Context;
67
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
78
import io.javaoperatorsdk.operator.api.reconciler.Ignore;
89
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceNotFoundException;
@@ -94,15 +95,17 @@ public Optional<ResourceEventSource<R, P>> eventSource() {
9495
return Optional.ofNullable(eventSource);
9596
}
9697

97-
protected void onCreated(ResourceID primaryResourceId, R created) {
98+
protected void onCreated(P primary, R created, Context<P> context) {
9899
if (isCacheFillerEventSource) {
99-
recentOperationCacheFiller().handleRecentResourceCreate(primaryResourceId, created);
100+
recentOperationCacheFiller().handleRecentResourceCreate(ResourceID.fromResource(primary),
101+
created);
100102
}
101103
}
102104

103-
protected void onUpdated(ResourceID primaryResourceId, R updated, R actual) {
105+
protected void onUpdated(P primary, R updated, R actual, Context<P> context) {
104106
if (isCacheFillerEventSource) {
105-
recentOperationCacheFiller().handleRecentResourceUpdate(primaryResourceId, updated, actual);
107+
recentOperationCacheFiller().handleRecentResourceUpdate(ResourceID.fromResource(primary),
108+
updated, actual);
106109
}
107110
}
108111

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.javaoperatorsdk.operator.processing.dependent;
2+
3+
import io.fabric8.kubernetes.api.model.HasMetadata;
4+
import io.javaoperatorsdk.operator.api.reconciler.Context;
5+
import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller;
6+
import io.javaoperatorsdk.operator.processing.event.ResourceID;
7+
import io.javaoperatorsdk.operator.processing.event.source.ResourceEventSource;
8+
9+
public abstract class AbstractExternalDependentResource<R, P extends HasMetadata, T extends ResourceEventSource<R, P>>
10+
extends AbstractEventSourceHolderDependentResource<R, P, T> {
11+
12+
protected AbstractExternalDependentResource(Class<R> resourceType) {
13+
super(resourceType);
14+
}
15+
16+
@Override
17+
protected void onCreated(P primary, R created, Context<P> context) {
18+
super.onCreated(primary, created, context);
19+
if (this instanceof ExplicitIDHandler) {
20+
handleExplicitIDStoring(primary, created, context);
21+
}
22+
}
23+
24+
@SuppressWarnings({"rawtypes", "unchecked"})
25+
protected void handleExplicitIDStoring(P primary, R created, Context<P> context) {
26+
ExplicitIDHandler<R, P, ?> handler = (ExplicitIDHandler) this;
27+
HasMetadata resource = handler.stateResource(primary, created);
28+
var stateResource = handler.getKubernetesClient().resource(resource).create();
29+
30+
String name = handler.eventSourceName().orElse(null);
31+
ResourceEventSource<R, P> eventSource;
32+
if (name == null) {
33+
eventSource =
34+
context.eventSourceRetriever()
35+
.<R>getResourceEventSourceFor((Class<R>) resource.getClass());
36+
} else {
37+
eventSource = context.eventSourceRetriever()
38+
.<R>getResourceEventSourceFor((Class<R>) resource.getClass(), name);
39+
}
40+
if (eventSource instanceof RecentOperationCacheFiller) {
41+
((RecentOperationCacheFiller) eventSource)
42+
.handleRecentResourceCreate(ResourceID.fromResource(primary), stateResource);
43+
}
44+
}
45+
46+
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResourceReconciler.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter;
1212
import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult;
1313
import io.javaoperatorsdk.operator.processing.dependent.Matcher.Result;
14-
import io.javaoperatorsdk.operator.processing.event.ResourceID;
1514

1615
class BulkDependentResourceReconciler<R, P extends HasMetadata>
1716
implements DependentResourceReconciler<R, P> {
@@ -97,13 +96,13 @@ public Result<R> match(R resource, P primary, Context<P> context) {
9796
}
9897

9998
@Override
100-
protected void onCreated(ResourceID primaryResourceId, R created) {
101-
asAbstractDependentResource().onCreated(primaryResourceId, created);
99+
protected void onCreated(P primary, R created, Context<P> context) {
100+
asAbstractDependentResource().onCreated(primary, created, context);
102101
}
103102

104103
@Override
105-
protected void onUpdated(ResourceID primaryResourceId, R updated, R actual) {
106-
asAbstractDependentResource().onUpdated(primaryResourceId, updated, actual);
104+
protected void onUpdated(P primary, R updated, R actual, Context<P> context) {
105+
asAbstractDependentResource().onUpdated(primary, updated, actual, context);
107106
}
108107

109108
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.javaoperatorsdk.operator.processing.dependent;
2+
3+
import java.util.Optional;
4+
5+
import io.fabric8.kubernetes.api.model.HasMetadata;
6+
import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter;
7+
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.KubernetesClientAware;
8+
9+
public interface ExplicitIDHandler<R, P extends HasMetadata, S extends HasMetadata>
10+
extends Creator<R, P>, Deleter<P>, KubernetesClientAware {
11+
12+
default Optional<String> eventSourceName() {
13+
return Optional.empty();
14+
}
15+
16+
S stateResource(P primary, R resource);
17+
18+
// todo for the two phase resource create
19+
// void postIDStored(P primary, R resource, S stateResource);
20+
21+
}

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import io.fabric8.kubernetes.api.model.ConfigMap;
88
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
99
import io.javaoperatorsdk.operator.api.reconciler.Context;
10-
import io.javaoperatorsdk.operator.processing.event.ResourceID;
1110
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
1211

1312
import static org.junit.jupiter.api.Assertions.*;
@@ -85,10 +84,12 @@ public Optional<ConfigMap> getSecondaryResource(TestCustomResource primary,
8584
}
8685

8786
@Override
88-
protected void onCreated(ResourceID primaryResourceId, ConfigMap created) {}
87+
protected void onCreated(TestCustomResource primary, ConfigMap created,
88+
Context<TestCustomResource> context) {}
8989

9090
@Override
91-
protected void onUpdated(ResourceID primaryResourceId, ConfigMap updated, ConfigMap actual) {}
91+
protected void onUpdated(TestCustomResource primary, ConfigMap updated, ConfigMap actual,
92+
Context<TestCustomResource> context) {}
9293

9394
@Override
9495
protected ConfigMap desired(TestCustomResource primary, Context<TestCustomResource> context) {

0 commit comments

Comments
 (0)