Skip to content

Commit

Permalink
improve: remove EventSourceInitializer (#2257)
Browse files Browse the repository at this point in the history
Signed-off-by: Attila Mészáros <csviri@gmail.com>
Signed-off-by: Chris Laprun <claprun@redhat.com>
Co-authored-by: Chris Laprun <claprun@redhat.com>
Signed-off-by: Attila Mészáros <csviri@gmail.com>
  • Loading branch information
csviri and metacosm committed Sep 20, 2024
1 parent 0f727c8 commit 3c25d9f
Show file tree
Hide file tree
Showing 40 changed files with 155 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import com.github.benmanes.caffeine.cache.Caffeine;

public abstract class AbstractTestReconciler<P extends CustomResource<BoundedCacheTestSpec, BoundedCacheTestStatus>>
implements Reconciler<P>, EventSourceInitializer<P> {
implements Reconciler<P> {

private static final Logger log =
LoggerFactory.getLogger(BoundedCacheClusterScopeTestReconciler.class);
Expand Down Expand Up @@ -82,7 +82,7 @@ public Map<String, EventSource> prepareEventSources(
Mappers.fromOwnerReference(this instanceof BoundedCacheClusterScopeTestReconciler))
.build(), context);

return EventSourceInitializer.nameEventSources(es);
return EventSourceUtils.nameEventSources(es);
}

private void ensureStatus(P resource) {
Expand Down
5 changes: 5 additions & 0 deletions docs/documentation/v5-0-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ permalink: /docs/v5-0-migration
1. [Result of managed dependent resources](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java#L55-L57)
is not `Optional` anymore. In case you use this result, simply use the result
objects directly.
2. `EventSourceInitializer` is not a separate interface anymore. It is part of the `Reconciler` interface with a
default implementation. You can simply remove this interface from your reconciler. The
[`EventSourceUtils`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceUtils.java#L11-L11)
now contains all the utility methods used for event sources naming that were previously defined in
the `EventSourceInitializer` interface.
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,15 @@
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
import io.javaoperatorsdk.operator.processing.event.source.ResourceEventSource;

/**
* An interface that a {@link Reconciler} can implement to have the SDK register the provided
* {@link EventSource}
*
* @param <P> the primary resource type handled by the associated {@link Reconciler}
*/
public interface EventSourceInitializer<P extends HasMetadata> {

/**
* Prepares a map of {@link EventSource} implementations keyed by the name with which they need to
* be registered by the SDK.
*
* @param context a {@link EventSourceContext} providing access to information useful to event
* sources
* @return a map of event sources to register
*/
Map<String, EventSource> prepareEventSources(EventSourceContext<P> context);

public class EventSourceUtils {
/**
* Utility method to easily create map with generated name for event sources. This is for the use
* case when the event sources are not access explicitly by name in the reconciler.
*
* @param eventSources to name
* @return even source with default names
*/
static Map<String, EventSource> nameEventSources(EventSource... eventSources) {
public static Map<String, EventSource> nameEventSources(EventSource... eventSources) {
Map<String, EventSource> eventSourceMap = new HashMap<>(eventSources.length);
for (EventSource eventSource : eventSources) {
eventSourceMap.put(generateNameFor(eventSource), eventSource);
Expand All @@ -42,7 +25,7 @@ static Map<String, EventSource> nameEventSources(EventSource... eventSources) {
}

@SuppressWarnings("unchecked")
static <K extends HasMetadata> Map<String, EventSource> eventSourcesFromWorkflow(
public static <K extends HasMetadata> Map<String, EventSource> eventSourcesFromWorkflow(
EventSourceContext<K> context,
Workflow<K> workflow) {
Map<String, EventSource> result = new HashMap<>();
Expand All @@ -54,13 +37,13 @@ static <K extends HasMetadata> Map<String, EventSource> eventSourcesFromWorkflow
}

@SuppressWarnings("rawtypes")
static <K extends HasMetadata> Map<String, EventSource> nameEventSourcesFromDependentResource(
public static <K extends HasMetadata> Map<String, EventSource> nameEventSourcesFromDependentResource(
EventSourceContext<K> context, DependentResource... dependentResources) {
return nameEventSourcesFromDependentResource(context, Arrays.asList(dependentResources));
}

@SuppressWarnings("unchecked,rawtypes")
static <K extends HasMetadata> Map<String, EventSource> nameEventSourcesFromDependentResource(
public static <K extends HasMetadata> Map<String, EventSource> nameEventSourcesFromDependentResource(
EventSourceContext<K> context, Collection<DependentResource> dependentResources) {

if (dependentResources != null) {
Expand All @@ -81,9 +64,8 @@ static <K extends HasMetadata> Map<String, EventSource> nameEventSourcesFromDepe
* @param eventSource EventSource
* @return generated name
*/
static String generateNameFor(EventSource eventSource) {
public static String generateNameFor(EventSource eventSource) {
// we can have multiple event sources for the same class
return eventSource.getClass().getName() + "#" + eventSource.hashCode();
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package io.javaoperatorsdk.operator.api.reconciler;

import java.util.*;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.processing.event.source.EventSource;

public interface Reconciler<R extends HasMetadata> {
public interface Reconciler<P extends HasMetadata> {

/**
* The implementation of this operation is required to be idempotent. Always use the UpdateControl
Expand All @@ -14,6 +17,19 @@ public interface Reconciler<R extends HasMetadata> {
* @return UpdateControl to manage updates on the custom resource (usually the status) after
* reconciliation.
*/
UpdateControl<R> reconcile(R resource, Context<R> context) throws Exception;
UpdateControl<P> reconcile(P resource, Context<P> context) throws Exception;


/**
* Prepares a map of {@link EventSource} implementations keyed by the name with which they need to
* be registered by the SDK.
*
* @param context a {@link EventSourceContext} providing access to information useful to event
* sources
* @return a map of event sources to register
*/
default Map<String, EventSource> prepareEventSources(EventSourceContext<P> context) {
return Map.of();
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package io.javaoperatorsdk.operator.processing;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -25,16 +20,7 @@
import io.javaoperatorsdk.operator.api.config.ExecutorServiceManager;
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
import io.javaoperatorsdk.operator.api.monitoring.Metrics.ControllerExecution;
import io.javaoperatorsdk.operator.api.reconciler.Cleaner;
import io.javaoperatorsdk.operator.api.reconciler.Constants;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.ContextInitializer;
import io.javaoperatorsdk.operator.api.reconciler.DeleteControl;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer;
import io.javaoperatorsdk.operator.api.reconciler.Ignore;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
import io.javaoperatorsdk.operator.api.reconciler.*;
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceNotFoundException;
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceProvider;
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceReferencer;
Expand Down Expand Up @@ -230,11 +216,8 @@ private void initContextIfNeeded(P resource, Context<P> context) {
}

public void initAndRegisterEventSources(EventSourceContext<P> context) {
if (reconciler instanceof EventSourceInitializer) {
final var provider = (EventSourceInitializer<P>) this.reconciler;
final var ownSources = provider.prepareEventSources(context);
ownSources.forEach(eventSourceManager::registerEventSource);
}
final var ownSources = this.reconciler.prepareEventSources(context);
ownSources.forEach(eventSourceManager::registerEventSource);

// register created event sources
final var dependentResourcesByName =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import io.javaoperatorsdk.operator.api.config.ExecutorServiceManager;
import io.javaoperatorsdk.operator.api.config.NamespaceChangeable;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceUtils;
import io.javaoperatorsdk.operator.processing.Controller;
import io.javaoperatorsdk.operator.processing.LifecycleAware;
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
Expand Down Expand Up @@ -150,7 +150,7 @@ public final synchronized void registerEventSource(String name, EventSource even
Objects.requireNonNull(eventSource, "EventSource must not be null");
try {
if (name == null || name.isBlank()) {
name = EventSourceInitializer.generateNameFor(eventSource);
name = EventSourceUtils.generateNameFor(eventSource);
}
if (eventSource instanceof ManagedInformerEventSource) {
var managedInformerEventSource = ((ManagedInformerEventSource) eventSource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.Optional;

import io.javaoperatorsdk.operator.OperatorException;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceUtils;
import io.javaoperatorsdk.operator.processing.event.source.Configurable;
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
import io.javaoperatorsdk.operator.processing.event.source.EventSourceStartPriority;
Expand All @@ -19,7 +19,7 @@ class NamedEventSource implements EventSource, EventSourceMetadata {
NamedEventSource(EventSource original, String name) {
this.original = original;
this.name = name;
nameSet = !name.equals(EventSourceInitializer.generateNameFor(original));
nameSet = !name.equals(EventSourceUtils.generateNameFor(original));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

/**
* Creates an event source to trigger your reconciler whenever something happens to a secondary or
* external resource that would not normally trigger your reconciler (as the primary resources are
* not changed). To register EventSources with so that your reconciler is triggered, please make
* your reconciler implement
* {@link io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer}.
* external resource that should cause a reconciliation of the primary resource. EventSource
* generalizes the concept of Informers and extends it to external (i.e. non Kubernetes) resources.
*/
public interface EventSource extends LifecycleAware, EventSourceHealthIndicator {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

import static org.assertj.core.api.Assertions.assertThat;

class EventSourceInitializerTest {
class EventSourceUtilsTest {

@Test
@SuppressWarnings({"rawtypes", "unchecked"})
void defaultNameDifferentForOtherInstance() {
var eventSource1 = new PollingEventSource(HashMap::new, 1000, String.class);
var eventSource2 = new PollingEventSource(HashMap::new, 1000, String.class);
var eventSourceName1 = EventSourceInitializer.generateNameFor(eventSource1);
var eventSourceName2 = EventSourceInitializer.generateNameFor(eventSource2);
var eventSourceName1 = EventSourceUtils.generateNameFor(eventSource1);
var eventSourceName2 = EventSourceUtils.generateNameFor(eventSource2);

assertThat(eventSourceName1).isNotEqualTo(eventSourceName2);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import io.javaoperatorsdk.operator.TestUtils;
import io.javaoperatorsdk.operator.api.config.BaseConfigurationService;
import io.javaoperatorsdk.operator.api.config.ResolvedControllerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
import io.javaoperatorsdk.operator.processing.Controller;
import io.javaoperatorsdk.operator.processing.event.EventHandler;
import io.javaoperatorsdk.operator.processing.event.EventSourceManager;
Expand Down Expand Up @@ -152,18 +154,21 @@ void genericFilterFiltersOutAddUpdateAndDeleteEvents() {
@SuppressWarnings("unchecked")
private static class TestController extends Controller<TestCustomResource> {

private static final Reconciler<TestCustomResource> reconciler =
(resource, context) -> UpdateControl.noUpdate();

private final EventSourceManager<TestCustomResource> eventSourceManager =
mock(EventSourceManager.class);

public TestController(OnAddFilter<TestCustomResource> onAddFilter,
OnUpdateFilter<TestCustomResource> onUpdateFilter,
GenericFilter<TestCustomResource> genericFilter) {
super(null, new TestConfiguration(true, onAddFilter, onUpdateFilter, genericFilter),
super(reconciler, new TestConfiguration(true, onAddFilter, onUpdateFilter, genericFilter),
MockKubernetesClient.client(TestCustomResource.class));
}

public TestController(boolean generationAware) {
super(null, new TestConfiguration(generationAware, null, null, null),
super(reconciler, new TestConfiguration(generationAware, null, null, null),
MockKubernetesClient.client(TestCustomResource.class));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

@ControllerConfiguration
public class StandaloneBulkDependentReconciler
implements Reconciler<BulkDependentTestCustomResource>, TestExecutionInfoProvider,
EventSourceInitializer<BulkDependentTestCustomResource> {
implements Reconciler<BulkDependentTestCustomResource>, TestExecutionInfoProvider {

private final AtomicInteger numberOfExecutions = new AtomicInteger(0);

Expand Down Expand Up @@ -38,7 +37,7 @@ public int getNumberOfExecutions() {
@Override
public Map<String, EventSource> prepareEventSources(
EventSourceContext<BulkDependentTestCustomResource> context) {
return EventSourceInitializer
return EventSourceUtils
.nameEventSources(dependent.initEventSource(context));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@

@ControllerConfiguration
public class ChangeNamespaceTestReconciler
implements Reconciler<ChangeNamespaceTestCustomResource>,
EventSourceInitializer<ChangeNamespaceTestCustomResource> {
implements Reconciler<ChangeNamespaceTestCustomResource> {

private final ConcurrentHashMap<ResourceID, Integer> numberOfResourceReconciliations =
new ConcurrentHashMap<>();
Expand All @@ -27,7 +26,7 @@ public Map<String, EventSource> prepareEventSources(
new InformerEventSource<>(InformerConfiguration.from(ConfigMap.class, context)
.build(), context);

return EventSourceInitializer.nameEventSources(configMapES);
return EventSourceUtils.nameEventSources(configMapES);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@

@ControllerConfiguration
public class ClusterScopedCustomResourceReconciler
implements Reconciler<ClusterScopedCustomResource>,
EventSourceInitializer<ClusterScopedCustomResource> {
implements Reconciler<ClusterScopedCustomResource> {

public static final String DATA_KEY = "data-key";

Expand Down Expand Up @@ -59,6 +58,6 @@ public Map<String, EventSource> prepareEventSources(
.withSecondaryToPrimaryMapper(Mappers.fromOwnerReference(true))
.withLabelSelector(TEST_LABEL_KEY + "=" + TEST_LABEL_VALUE)
.build(), context);
return EventSourceInitializer.nameEventSources(ies);
return EventSourceUtils.nameEventSources(ies);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
readyPostcondition = StatefulSetReadyCondition.class),
})
@ControllerConfiguration(name = "project-operator")
public class ComplexDependentReconciler implements Reconciler<ComplexDependentCustomResource>,
EventSourceInitializer<ComplexDependentCustomResource> {
public class ComplexDependentReconciler implements Reconciler<ComplexDependentCustomResource> {

public static final String SERVICE_EVENT_SOURCE_NAME = "serviceEventSource";
public static final String STATEFUL_SET_EVENT_SOURCE_NAME = "statefulSetEventSource";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@

@ControllerConfiguration
public class CreateUpdateEventFilterTestReconciler
implements Reconciler<CreateUpdateEventFilterTestCustomResource>,
EventSourceInitializer<CreateUpdateEventFilterTestCustomResource> {
implements Reconciler<CreateUpdateEventFilterTestCustomResource> {

private static final class DirectConfigMapDependentResource
extends
Expand Down Expand Up @@ -97,7 +96,7 @@ public Map<String, EventSource> prepareEventSources(
informerEventSource = new InformerEventSource<>(informerConfiguration, context.getClient());
this.configMapDR.setEventSource(informerEventSource);

return EventSourceInitializer.nameEventSources(informerEventSource);
return EventSourceUtils.nameEventSources(informerEventSource);
}

public int getNumberOfExecutions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

@ControllerConfiguration
public class DependentReInitializationReconciler
implements Reconciler<DependentReInitializationCustomResource>,
EventSourceInitializer<DependentReInitializationCustomResource> {
implements Reconciler<DependentReInitializationCustomResource> {

private final ConfigMapDependentResource configMapDependentResource;

Expand All @@ -27,7 +26,7 @@ public UpdateControl<DependentReInitializationCustomResource> reconcile(
@Override
public Map<String, EventSource> prepareEventSources(
EventSourceContext<DependentReInitializationCustomResource> context) {
return EventSourceInitializer.nameEventSourcesFromDependentResource(context,
return EventSourceUtils.nameEventSourcesFromDependentResource(context,
configMapDependentResource);
}

Expand Down
Loading

0 comments on commit 3c25d9f

Please sign in to comment.