1
1
package io .javaoperatorsdk .operator .processing .dependent ;
2
2
3
+ import java .util .ArrayList ;
4
+ import java .util .List ;
3
5
import java .util .Optional ;
4
6
5
7
import org .slf4j .Logger ;
@@ -24,23 +26,54 @@ public abstract class AbstractDependentResource<R, P extends HasMetadata>
24
26
protected Creator <R , P > creator ;
25
27
protected Updater <R , P > updater ;
26
28
27
- // todo discuss, rather implement this as interface?
28
- private ResourceDiscriminator <R , P > resourceDiscriminator ;
29
+ protected List <ResourceDiscriminator <R , P >> resourceDiscriminator = new ArrayList <>(1 );
30
+ // used just for bulk creation
31
+ protected BulkResourceDiscriminatorFactory <R , P > bulkResourceDiscriminatorFactory ;
29
32
30
33
@ SuppressWarnings ("unchecked" )
31
34
public AbstractDependentResource () {
32
35
creator = creatable ? (Creator <R , P >) this : null ;
33
36
updater = updatable ? (Updater <R , P >) this : null ;
34
37
}
35
38
36
- @ SuppressWarnings ("unchecked" )
37
39
@ Override
38
40
public ReconcileResult <R > reconcile (P primary , Context <P > context ) {
39
- Optional <R > maybeActual = getSecondaryResource (primary , context );
41
+ var count = count (primary , context );
42
+ if (isBulkResourceCreation (primary , context )) {
43
+ initDiscriminators (count );
44
+ }
45
+ for (int i = 0 ; i < count ; i ++) {
46
+ reconcileWithIndex (primary , i , context );
47
+ }
48
+ // todo result
49
+ return null ;
50
+ }
51
+
52
+ private void initDiscriminators (int count ) {
53
+ if (resourceDiscriminator .size () == count ) {
54
+ return ;
55
+ }
56
+ if (resourceDiscriminator .size () < count ) {
57
+ for (int i = resourceDiscriminator .size () - 1 ; i < count ; i ++) {
58
+ resourceDiscriminator .add (bulkResourceDiscriminatorFactory .createResourceDiscriminator (i ));
59
+ }
60
+ }
61
+ if (resourceDiscriminator .size () < count ) {
62
+ for (int i = resourceDiscriminator .size () - 1 ; i < count ; i ++) {
63
+ resourceDiscriminator .add (bulkResourceDiscriminatorFactory .createResourceDiscriminator (i ));
64
+ }
65
+ }
66
+ if (resourceDiscriminator .size () > count ) {
67
+ resourceDiscriminator .subList (count , resourceDiscriminator .size ()).clear ();
68
+ }
69
+ }
70
+
71
+ protected ReconcileResult <R > reconcileWithIndex (P primary , int i , Context <P > context ) {
72
+ Optional <R > maybeActual = getSecondaryResource (primary , i , context );
40
73
if (creatable || updatable ) {
41
74
if (maybeActual .isEmpty ()) {
42
75
if (creatable ) {
43
- var desired = desired (primary , context );
76
+ var desired = desired (primary , i , context );
44
77
throwIfNull (desired , primary , "Desired" );
45
78
logForOperation ("Creating" , primary , desired );
46
79
var createdResource = handleCreate (desired , primary , context );
@@ -49,7 +82,8 @@ public ReconcileResult<R> reconcile(P primary, Context<P> context) {
49
82
} else {
50
83
final var actual = maybeActual .get ();
51
84
if (updatable ) {
52
- final var match = updater .match (actual , primary , context );
85
+ // todo simplify matcher?
86
+ final var match = updater .match (actual , primary , i , context );
53
87
if (!match .matched ()) {
54
88
final var desired = match .computedDesired ().orElse (desired (primary , context ));
55
89
throwIfNull (desired , primary , "Desired" );
@@ -69,14 +103,27 @@ public ReconcileResult<R> reconcile(P primary, Context<P> context) {
69
103
return ReconcileResult .noOperation (maybeActual .orElse (null ));
70
104
}
71
105
106
+ // todo check
72
107
protected Optional <R > getSecondaryResource (P primary , Context <P > context ) {
73
- if (resourceDiscriminator == null ) {
108
+ if (resourceDiscriminator . isEmpty () ) {
74
109
return context .getSecondaryResource (resourceType ());
75
110
} else {
76
- return context .getSecondaryResource (resourceType (), resourceDiscriminator );
111
+ return context .getSecondaryResource (resourceType (), resourceDiscriminator . get ( 0 ) );
77
112
}
78
113
}
79
114
115
+ protected Optional <R > getSecondaryResource (P primary , int index , Context <P > context ) {
116
+ if (index > 0 && resourceDiscriminator .isEmpty ()) {
117
+ throw new IllegalStateException (
118
+ "Handling resources in bulk bot no resource discriminators set." );
119
+ }
120
+ if (!isBulkResourceCreation (primary , context )) {
121
+ return getSecondaryResource (primary , context );
122
+ }
123
+
124
+ return context .getSecondaryResource (resourceType (), resourceDiscriminator .get (index ));
125
+ }
126
+
80
127
private void throwIfNull (R desired , P primary , String descriptor ) {
81
128
if (desired == null ) {
82
129
throw new DependentResourceException (
@@ -112,7 +159,7 @@ protected R handleCreate(R desired, P primary, Context<P> context) {
112
159
protected abstract void onCreated (ResourceID primaryResourceId , R created );
113
160
114
161
/**
115
- * Allows sub-classes to perform additional processing on the updated resource if needed.
162
+ * Allows subclasses to perform additional processing on the updated resource if needed.
116
163
*
117
164
* @param primaryResourceId the {@link ResourceID} of the primary resource associated with the
118
165
* newly updated resource
@@ -134,14 +181,36 @@ protected R desired(P primary, Context<P> context) {
134
181
"desired method must be implemented if this DependentResource can be created and/or updated" );
135
182
}
136
183
137
- // todo review & refactor configuration to cover all cases
138
- public ResourceDiscriminator <R , P > getResourceDiscriminator () {
139
- return resourceDiscriminator ;
184
+ protected R desired (P primary , int index , Context <P > context ) {
185
+ if (!isBulkResourceCreation (primary , context )) {
186
+ return desired (primary , context );
187
+ } else {
188
+ throw new IllegalStateException (
189
+ "desired() with index method must be implemented for bulk DependentResource creation" );
190
+ }
140
191
}
141
192
142
193
public AbstractDependentResource <R , P > setResourceDiscriminator (
143
194
ResourceDiscriminator <R , P > resourceDiscriminator ) {
144
- this .resourceDiscriminator = resourceDiscriminator ;
195
+ this .resourceDiscriminator .add (resourceDiscriminator );
196
+ return this ;
197
+ }
198
+
199
+ protected int count (P primary , Context <P > context ) {
200
+ return 1 ;
201
+ }
202
+
203
+ protected boolean isBulkResourceCreation (P primary , Context <P > context ) {
204
+ return false ;
205
+ }
206
+
207
+ public BulkResourceDiscriminatorFactory <R , P > getBulkResourceDiscriminatorFactory () {
208
+ return bulkResourceDiscriminatorFactory ;
209
+ }
210
+
211
+ public AbstractDependentResource <R , P > setBulkResourceDiscriminatorFactory (
212
+ BulkResourceDiscriminatorFactory <R , P > bulkResourceDiscriminatorFactory ) {
213
+ this .bulkResourceDiscriminatorFactory = bulkResourceDiscriminatorFactory ;
145
214
return this ;
146
215
}
147
216
}
0 commit comments