@@ -86,6 +86,35 @@ possible to not implement any of these traits and therefore create read-only dep
86
86
that will trigger your reconciler whenever a user interacts with them but that are never
87
87
modified by your reconciler itself.
88
88
89
+ [ ` AbstractSimpleDependentResource ` ] ( https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResource.java )
90
+ and [ ` KubernetesDependentResource ` ] ( https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java )
91
+ sub-classes can also implement
92
+ the [ ` Matcher ` ] ( https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Matcher.java )
93
+ interface to customize how the SDK decides whether or not the actual state of the dependent
94
+ matches the desired state. This makes it convenient to use these abstract base classes for your
95
+ implementation, only customizing the matching logic. Note that in many cases, there is no need
96
+ to customize that logic as the SDK already provides convenient default implementations in the
97
+ form
98
+ of [ ` DesiredEqualsMatcher ` ] ( https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DesiredEqualsMatcher.java )
99
+ and
100
+ [ ` GenericKubernetesResourceMatcher ` ] ( https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java )
101
+ implementations, respectively. If you want to provide custom logic, you only need your
102
+ ` DependentResource ` implementation to implement the ` Matcher ` interface as below, which shows
103
+ how to customize the default matching logic for Kubernetes resource to also consider annotations
104
+ and labels, which are ignored by default:
105
+
106
+ ``` java
107
+ public class MyDependentResource extends KubernetesDependentResource<MyDependent , MyPrimary >
108
+ implements Matcher<MyDependent , MyPrimary > {
109
+ // your implementation
110
+
111
+ public Result<MyDependent > match (MyDependent actualResource , MyPrimary primary ,
112
+ Context<MyPrimary > context ) {
113
+ return GenericKubernetesResourceMatcher . match(this , actualResource, primary, context, true );
114
+ }
115
+ }
116
+ ```
117
+
89
118
### Batteries included: convenient DependentResource implementations!
90
119
91
120
JOSDK also offers several other convenient implementations building on top of
@@ -116,7 +145,7 @@ Deleted (or set to be garbage collected). The following example shows how to cre
116
145
@KubernetesDependent (labelSelector = WebPageManagedDependentsReconciler . SELECTOR )
117
146
class DeploymentDependentResource extends CRUDKubernetesDependentResource<Deployment , WebPage > {
118
147
119
- public DeploymentDependentResource () {
148
+ public DeploymentDependentResource () {
120
149
super (Deployment . class);
121
150
}
122
151
@@ -169,26 +198,26 @@ instances are managed by JOSDK, an example of which can be seen below:
169
198
``` java
170
199
171
200
@ControllerConfiguration (
172
- labelSelector = SELECTOR ,
173
- dependents = {
174
- @Dependent (type = ConfigMapDependentResource . class),
175
- @Dependent (type = DeploymentDependentResource . class),
176
- @Dependent (type = ServiceDependentResource . class)
177
- })
201
+ labelSelector = SELECTOR ,
202
+ dependents = {
203
+ @Dependent (type = ConfigMapDependentResource . class),
204
+ @Dependent (type = DeploymentDependentResource . class),
205
+ @Dependent (type = ServiceDependentResource . class)
206
+ })
178
207
public class WebPageManagedDependentsReconciler
179
- implements Reconciler<WebPage > , ErrorStatusHandler<WebPage > {
208
+ implements Reconciler<WebPage > , ErrorStatusHandler<WebPage > {
180
209
181
- // omitted code
210
+ // omitted code
182
211
183
- @Override
184
- public UpdateControl<WebPage > reconcile (WebPage webPage , Context<WebPage > context )
185
- throws Exception {
212
+ @Override
213
+ public UpdateControl<WebPage > reconcile (WebPage webPage , Context<WebPage > context )
214
+ throws Exception {
186
215
187
- final var name = context. getSecondaryResource(ConfigMap . class). orElseThrow()
188
- .getMetadata(). getName();
189
- webPage. setStatus(createStatus(name));
190
- return UpdateControl . patchStatus(webPage);
191
- }
216
+ final var name = context. getSecondaryResource(ConfigMap . class). orElseThrow()
217
+ .getMetadata(). getName();
218
+ webPage. setStatus(createStatus(name));
219
+ return UpdateControl . patchStatus(webPage);
220
+ }
192
221
193
222
}
194
223
```
@@ -215,69 +244,69 @@ an `Ingress`:
215
244
216
245
@ControllerConfiguration
217
246
public class WebPageStandaloneDependentsReconciler
218
- implements Reconciler<WebPage > , ErrorStatusHandler<WebPage > ,
219
- EventSourceInitializer<WebPage > {
220
-
221
- private KubernetesDependentResource<ConfigMap , WebPage > configMapDR;
222
- private KubernetesDependentResource<Deployment , WebPage > deploymentDR;
223
- private KubernetesDependentResource<Service , WebPage > serviceDR;
224
- private KubernetesDependentResource<Service , WebPage > ingressDR;
225
-
226
- public WebPageStandaloneDependentsReconciler (KubernetesClient kubernetesClient ) {
227
- // 1.
228
- createDependentResources(kubernetesClient);
229
- }
230
-
231
- @Override
232
- public List<EventSource > prepareEventSources (EventSourceContext<WebPage > context ) {
233
- // 2.
234
- return List . of(
235
- configMapDR. initEventSource(context),
236
- deploymentDR. initEventSource(context),
237
- serviceDR. initEventSource(context));
238
- }
239
-
240
- @Override
241
- public UpdateControl<WebPage > reconcile (WebPage webPage , Context<WebPage > context )
242
- throws Exception {
243
-
244
- // 3.
245
- if (! isValidHtml(webPage. getHtml())) {
246
- return UpdateControl . patchStatus(setInvalidHtmlErrorMessage(webPage));
247
- }
248
-
249
- // 4.
250
- configMapDR. reconcile(webPage, context);
251
- deploymentDR. reconcile(webPage, context);
252
- serviceDR. reconcile(webPage, context);
253
-
254
- // 5.
255
- if (Boolean . TRUE. equals(webPage. getSpec(). getExposed())) {
256
- ingressDR. reconcile(webPage, context);
257
- } else {
258
- ingressDR. delete(webPage, context);
259
- }
260
-
261
- // 6.
262
- webPage. setStatus(
263
- createStatus(configMapDR. getResource(webPage). orElseThrow(). getMetadata(). getName()));
264
- return UpdateControl . patchStatus(webPage);
265
- }
266
-
267
- private void createDependentResources (KubernetesClient client ) {
268
- this . configMapDR = new ConfigMapDependentResource ();
269
- this . deploymentDR = new DeploymentDependentResource ();
270
- this . serviceDR = new ServiceDependentResource ();
271
- this . ingressDR = new IngressDependentResource ();
272
-
273
- Arrays . asList(configMapDR, deploymentDR, serviceDR, ingressDR). forEach(dr - > {
274
- dr. setKubernetesClient(client);
275
- dr. configureWith(new KubernetesDependentResourceConfig ()
276
- .setLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR ));
277
- });
278
- }
279
-
280
- // omitted code
247
+ implements Reconciler<WebPage > , ErrorStatusHandler<WebPage > ,
248
+ EventSourceInitializer<WebPage > {
249
+
250
+ private KubernetesDependentResource<ConfigMap , WebPage > configMapDR;
251
+ private KubernetesDependentResource<Deployment , WebPage > deploymentDR;
252
+ private KubernetesDependentResource<Service , WebPage > serviceDR;
253
+ private KubernetesDependentResource<Service , WebPage > ingressDR;
254
+
255
+ public WebPageStandaloneDependentsReconciler (KubernetesClient kubernetesClient ) {
256
+ // 1.
257
+ createDependentResources(kubernetesClient);
258
+ }
259
+
260
+ @Override
261
+ public List<EventSource > prepareEventSources (EventSourceContext<WebPage > context ) {
262
+ // 2.
263
+ return List . of(
264
+ configMapDR. initEventSource(context),
265
+ deploymentDR. initEventSource(context),
266
+ serviceDR. initEventSource(context));
267
+ }
268
+
269
+ @Override
270
+ public UpdateControl<WebPage > reconcile (WebPage webPage , Context<WebPage > context )
271
+ throws Exception {
272
+
273
+ // 3.
274
+ if (! isValidHtml(webPage. getHtml())) {
275
+ return UpdateControl . patchStatus(setInvalidHtmlErrorMessage(webPage));
276
+ }
277
+
278
+ // 4.
279
+ configMapDR. reconcile(webPage, context);
280
+ deploymentDR. reconcile(webPage, context);
281
+ serviceDR. reconcile(webPage, context);
282
+
283
+ // 5.
284
+ if (Boolean . TRUE. equals(webPage. getSpec(). getExposed())) {
285
+ ingressDR. reconcile(webPage, context);
286
+ } else {
287
+ ingressDR. delete(webPage, context);
288
+ }
289
+
290
+ // 6.
291
+ webPage. setStatus(
292
+ createStatus(configMapDR. getResource(webPage). orElseThrow(). getMetadata(). getName()));
293
+ return UpdateControl . patchStatus(webPage);
294
+ }
295
+
296
+ private void createDependentResources (KubernetesClient client ) {
297
+ this . configMapDR = new ConfigMapDependentResource ();
298
+ this . deploymentDR = new DeploymentDependentResource ();
299
+ this . serviceDR = new ServiceDependentResource ();
300
+ this . ingressDR = new IngressDependentResource ();
301
+
302
+ Arrays . asList(configMapDR, deploymentDR, serviceDR, ingressDR). forEach(dr - > {
303
+ dr. setKubernetesClient(client);
304
+ dr. configureWith(new KubernetesDependentResourceConfig ()
305
+ .setLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR ));
306
+ });
307
+ }
308
+
309
+ // omitted code
281
310
}
282
311
```
283
312
0 commit comments