diff --git a/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md b/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md index 8a575f716f..c1e3ffc8e8 100644 --- a/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md +++ b/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md @@ -303,14 +303,15 @@ they should be reconciled. There might be cases, though, where it might be problematic to call the `desired` method several times (for example, because it is costly to do so), it is always possible to override this automated discrimination using several means (consider in this priority order): -- Override the `targetSecondaryResourceID` method, if your `DependentResource` extends `KubernetesDependentResource`, +- Override the [`targetSecondaryResourceID`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java#L282) + method, if your `DependentResource` extends `KubernetesDependentResource`, where it's very often possible to easily determine the `ResourceID` of the secondary resource. This would probably be - the easiest solution if you're working with Kubernetes resources. -- Override the `selectTargetSecondaryResource` method, if your `DependentResource` extends `AbstractDependentResource`. - This should be relatively simple to override this method to optimize the matching to your needs. You can see an - example of such an implementation in - the [`ExternalWithStateDependentResource`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalWithStateDependentResource.java) - class. + the easiest solution if you're working with Kubernetes resources. Similarly, you can override the + [`targetSecondaryResourceID`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java#L138) + for external resources. See below the related ID handling +- If the approach above doesn't fit your needs, you can override the target resource selection mechanism by overriding + `selectTargetSecondaryResource` for both [`KubernetesDependentResource`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java#L282) + and [`AbstractExternalDependentResource`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java#L148). - As last resort, you can implement your own `getSecondaryResource` method on your `DependentResource` implementation from scratch. ### Sharing an Event Source Between Dependent Resources diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java index 2c5be82288..ff8a5133ae 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java @@ -126,19 +126,34 @@ protected InformerEventSource getExternalStateEventSource() { return externalStateEventSource; } + /** + * Override this method to optimize and avoid computing the desired when selecting the target + * secondary resource. Return the target id. + * + * @see ExternalDependentIDProvider + * @param primary resource + * @param context of current reconciliation + * @return id of the target managed resource + */ + protected Optional targetSecondaryResourceID(P primary, Context

context) { + R desired = desired(primary, context); + if (desired instanceof ExternalDependentIDProvider desiredWithId) { + return Optional.of(desiredWithId.externalResourceId()); + } else { + return Optional.empty(); + } + } + @Override protected Optional selectTargetSecondaryResource( Set secondaryResources, P primary, Context

context) { - R desired = desired(primary, context); + var optionalId = targetSecondaryResourceID(primary, context); List targetResources; - if (desired instanceof ExternalDependentIDProvider desiredWithId) { + if (optionalId.isPresent()) { + var id = optionalId.get(); targetResources = secondaryResources.stream() - .filter( - r -> - ((ExternalDependentIDProvider) r) - .externalResourceId() - .equals(desiredWithId.externalResourceId())) + .filter(r -> ((ExternalDependentIDProvider) r).externalResourceId().equals(id)) .toList(); } else { throw new IllegalStateException(