11package io .javaoperatorsdk .operator .processing .dependent ;
22
3+ import java .util .ArrayList ;
4+ import java .util .List ;
35import java .util .Optional ;
46
57import org .slf4j .Logger ;
@@ -24,23 +26,54 @@ public abstract class AbstractDependentResource<R, P extends HasMetadata>
2426 protected Creator <R , P > creator ;
2527 protected Updater <R , P > updater ;
2628
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 ;
2932
3033 @ SuppressWarnings ("unchecked" )
3134 public AbstractDependentResource () {
3235 creator = creatable ? (Creator <R , P >) this : null ;
3336 updater = updatable ? (Updater <R , P >) this : null ;
3437 }
3538
36- @ SuppressWarnings ("unchecked" )
3739 @ Override
3840 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 );
4073 if (creatable || updatable ) {
4174 if (maybeActual .isEmpty ()) {
4275 if (creatable ) {
43- var desired = desired (primary , context );
76+ var desired = desired (primary , i , context );
4477 throwIfNull (desired , primary , "Desired" );
4578 logForOperation ("Creating" , primary , desired );
4679 var createdResource = handleCreate (desired , primary , context );
@@ -49,7 +82,8 @@ public ReconcileResult<R> reconcile(P primary, Context<P> context) {
4982 } else {
5083 final var actual = maybeActual .get ();
5184 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 );
5387 if (!match .matched ()) {
5488 final var desired = match .computedDesired ().orElse (desired (primary , context ));
5589 throwIfNull (desired , primary , "Desired" );
@@ -69,14 +103,27 @@ public ReconcileResult<R> reconcile(P primary, Context<P> context) {
69103 return ReconcileResult .noOperation (maybeActual .orElse (null ));
70104 }
71105
106+ // todo check
72107 protected Optional <R > getSecondaryResource (P primary , Context <P > context ) {
73- if (resourceDiscriminator == null ) {
108+ if (resourceDiscriminator . isEmpty () ) {
74109 return context .getSecondaryResource (resourceType ());
75110 } else {
76- return context .getSecondaryResource (resourceType (), resourceDiscriminator );
111+ return context .getSecondaryResource (resourceType (), resourceDiscriminator . get ( 0 ) );
77112 }
78113 }
79114
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+
80127 private void throwIfNull (R desired , P primary , String descriptor ) {
81128 if (desired == null ) {
82129 throw new DependentResourceException (
@@ -112,7 +159,7 @@ protected R handleCreate(R desired, P primary, Context<P> context) {
112159 protected abstract void onCreated (ResourceID primaryResourceId , R created );
113160
114161 /**
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.
116163 *
117164 * @param primaryResourceId the {@link ResourceID} of the primary resource associated with the
118165 * newly updated resource
@@ -134,14 +181,36 @@ protected R desired(P primary, Context<P> context) {
134181 "desired method must be implemented if this DependentResource can be created and/or updated" );
135182 }
136183
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+ }
140191 }
141192
142193 public AbstractDependentResource <R , P > setResourceDiscriminator (
143194 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 ;
145214 return this ;
146215 }
147216}
0 commit comments