Skip to content

Simplify controller registration and unify controller configuration #303

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 20, 2021
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.javaoperatorsdk.operator.api.ResourceController;
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.processing.CustomResourceCache;
import io.javaoperatorsdk.operator.processing.DefaultEventHandler;
import io.javaoperatorsdk.operator.processing.EventDispatcher;
Expand All @@ -30,42 +31,30 @@ public Operator(KubernetesClient k8sClient, ConfigurationService configurationSe

public <R extends CustomResource> void register(ResourceController<R> controller)
throws OperatorException {
final var configuration = configurationService.getConfigurationFor(controller);
if (configuration == null) {
register(controller, null);
}

public <R extends CustomResource> void register(
ResourceController<R> controller, ControllerConfiguration<R> configuration)
throws OperatorException {
final var existing = configurationService.getConfigurationFor(controller);
if (existing == null) {
log.warn(
"Skipping registration of {} controller named {} because its configuration cannot be found.\n"
+ "Known controllers are: {}",
controller.getClass().getCanonicalName(),
ControllerUtils.getNameFor(controller),
configurationService.getKnownControllerNames());
} else {
if (configuration == null) {
configuration = existing;
}
final var retry = GenericRetry.fromConfiguration(configuration.getRetryConfiguration());
final var targetNamespaces = configuration.getNamespaces().toArray(new String[] {});
registerController(controller, configuration.watchAllNamespaces(), retry, targetNamespaces);
}
}

public <R extends CustomResource> void registerControllerForAllNamespaces(
ResourceController<R> controller, Retry retry) throws OperatorException {
registerController(controller, true, retry);
}

public <R extends CustomResource> void registerControllerForAllNamespaces(
ResourceController<R> controller) throws OperatorException {
registerController(controller, true, null);
}

public <R extends CustomResource> void registerController(
ResourceController<R> controller, Retry retry, String... targetNamespaces)
throws OperatorException {
registerController(controller, false, retry, targetNamespaces);
}

public <R extends CustomResource> void registerController(
ResourceController<R> controller, String... targetNamespaces) throws OperatorException {
registerController(controller, false, null, targetNamespaces);
}

@SuppressWarnings("rawtypes")
private <R extends CustomResource> void registerController(
ResourceController<R> controller,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@

/**
* Specified which namespaces this Controller monitors for custom resources events. If no
* namespace is specified then the controller will monitor the namespace it is deployed in (or the
* namespace to which the Kubernetes client is connected to). To specify that the controller needs
* to monitor all namespaces, add {@link
* io.javaoperatorsdk.operator.api.config.ControllerConfiguration#WATCH_ALL_NAMESPACES_MARKER} to
* this field.
* namespace is specified then the controller will monitor all namespaces by default.
*
* @return the list of namespaces this controller monitors
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package io.javaoperatorsdk.operator.api.config;

import io.fabric8.kubernetes.client.CustomResource;
import java.util.Collections;
import java.util.Set;

public abstract class AbstractControllerConfiguration<R extends CustomResource>
implements ControllerConfiguration<R> {

private final String associatedControllerClassName;
private final String name;
private final String crdName;
private final String finalizer;
private final boolean generationAware;
private final Set<String> namespaces;
private final boolean watchAllNamespaces;
private final RetryConfiguration retryConfiguration;

public AbstractControllerConfiguration(
String associatedControllerClassName,
String name,
String crdName,
String finalizer,
boolean generationAware,
Set<String> namespaces,
RetryConfiguration retryConfiguration) {
this.associatedControllerClassName = associatedControllerClassName;
this.name = name;
this.crdName = crdName;
this.finalizer = finalizer;
this.generationAware = generationAware;
this.namespaces =
namespaces != null ? Collections.unmodifiableSet(namespaces) : Collections.emptySet();
this.watchAllNamespaces = this.namespaces.isEmpty();
this.retryConfiguration =
retryConfiguration == null
? ControllerConfiguration.super.getRetryConfiguration()
: retryConfiguration;
}

@Override
public String getName() {
return name;
}

@Override
public String getCRDName() {
return crdName;
}

@Override
public String getFinalizer() {
return finalizer;
}

@Override
public boolean isGenerationAware() {
return generationAware;
}

@Override
public String getAssociatedControllerClassName() {
return associatedControllerClassName;
}

@Override
public Set<String> getNamespaces() {
return namespaces;
}

@Override
public boolean watchAllNamespaces() {
return watchAllNamespaces;
}

@Override
public RetryConfiguration getRetryConfiguration() {
return retryConfiguration;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ default Set<String> getNamespaces() {
}

default boolean watchAllNamespaces() {
return getNamespaces().contains(WATCH_ALL_NAMESPACES_MARKER);
return getNamespaces().isEmpty();
}

default RetryConfiguration getRetryConfiguration() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package io.javaoperatorsdk.operator.api.config;

import io.fabric8.kubernetes.client.CustomResource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ControllerConfigurationOverrider<R extends CustomResource> {

private String finalizer;
private boolean generationAware;
private Set<String> namespaces;
private RetryConfiguration retry;
private final ControllerConfiguration<R> original;

private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
finalizer = original.getFinalizer();
generationAware = original.isGenerationAware();
namespaces = new HashSet<>(original.getNamespaces());
retry = original.getRetryConfiguration();
this.original = original;
}

public ControllerConfigurationOverrider<R> withFinalizer(String finalizer) {
this.finalizer = finalizer;
return this;
}

public ControllerConfigurationOverrider<R> withGenerationAware(boolean generationAware) {
this.generationAware = generationAware;
return this;
}

public ControllerConfigurationOverrider<R> withCurrentNamespace() {
namespaces.clear();
return this;
}

public ControllerConfigurationOverrider<R> addingNamespaces(String... namespaces) {
this.namespaces.addAll(List.of(namespaces));
return this;
}

public ControllerConfigurationOverrider<R> removingNamespaces(String... namespaces) {
this.namespaces.removeAll(List.of(namespaces));
return this;
}

public ControllerConfigurationOverrider<R> settingNamespace(String namespace) {
this.namespaces.clear();
this.namespaces.add(namespace);
return this;
}

public ControllerConfigurationOverrider<R> withRetry(RetryConfiguration retry) {
this.retry = retry;
return this;
}

public ControllerConfiguration<R> build() {
return new AbstractControllerConfiguration<R>(
original.getAssociatedControllerClassName(),
original.getName(),
original.getCRDName(),
finalizer,
generationAware,
namespaces,
retry) {
@Override
public Class<R> getCustomResourceClass() {
return original.getCustomResourceClass();
}
};
}

public static <R extends CustomResource> ControllerConfigurationOverrider<R> override(
ControllerConfiguration<R> original) {
return new ControllerConfigurationOverrider<>(original);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public interface RetryConfiguration {

int DEFAULT_MAX_ATTEMPTS = 5;
long DEFAULT_INITIAL_INTERVAL = 2000L;

double DEFAULT_MULTIPLIER = 1.5D;

default int getMaxAttempts() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
import io.javaoperatorsdk.operator.api.config.RetryConfiguration;

public class GenericRetry implements Retry {

public static final int DEFAULT_MAX_ATTEMPTS = 5;
public static final long DEFAULT_INITIAL_INTERVAL = 2000L;
public static final double DEFAULT_MULTIPLIER = 1.5D;

private int maxAttempts = DEFAULT_MAX_ATTEMPTS;
private long initialInterval = DEFAULT_INITIAL_INTERVAL;
private double intervalMultiplier = DEFAULT_MULTIPLIER;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.javaoperatorsdk.operator.processing.retry;

public interface Retry {
import io.javaoperatorsdk.operator.api.config.RetryConfiguration;

public interface Retry extends RetryConfiguration {

RetryExecution initExecution();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.javaoperatorsdk.quarkus.extension;

import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import java.util.List;
Expand All @@ -10,9 +9,8 @@
public class ExternalControllerConfiguration {

/**
* An optional list of comma-separated namespace names the controller should watch. If the list
* contains {@link ControllerConfiguration#WATCH_ALL_NAMESPACES_MARKER} then the controller will
* watch all namespaces.
* An optional list of comma-separated namespace names the controller should watch. If this
* property is left empty then the controller will watch all namespaces.
*/
@ConfigItem public Optional<List<String>> namespaces;

Expand Down
Loading