Skip to content

Commit

Permalink
Merge branch 'minor-optimization-on-registe-es' into k8s-dependent-mu…
Browse files Browse the repository at this point in the history
…ltiowner
  • Loading branch information
csviri committed Dec 20, 2023
2 parents 011c22c + 4b967a4 commit 621120f
Show file tree
Hide file tree
Showing 51 changed files with 909 additions and 40 deletions.
2 changes: 1 addition & 1 deletion bootstrapper-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>java-operator-sdk</artifactId>
<groupId>io.javaoperatorsdk</groupId>
<version>4.6.2-SNAPSHOT</version>
<version>4.7.0-SNAPSHOT</version>
</parent>

<artifactId>bootstrapper</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ private void addJavaFiles(File projectDir, String groupId, String artifactId) {
try {
var packages = groupId.replace(".", File.separator);
var targetDir = new File(projectDir, "src/main/java/" + packages);
var targetTestDir = new File(projectDir, "src/test/java/" + packages);
FileUtils.forceMkdir(targetDir);
var classFileNamePrefix = artifactClassId(artifactId);
JAVA_FILES.forEach(f -> addTemplatedFile(projectDir, f, groupId, artifactId, targetDir,
Expand All @@ -65,6 +66,9 @@ private void addJavaFiles(File projectDir, String groupId, String artifactId) {
addTemplatedFile(projectDir, "Runner.java", groupId, artifactId, targetDir, null);
addTemplatedFile(projectDir, "ConfigMapDependentResource.java", groupId, artifactId,
targetDir, null);
addTemplatedFile(projectDir, "ReconcilerIntegrationTest.java", groupId,
artifactId,
targetTestDir, artifactClassId(artifactId) + "ReconcilerIntegrationTest.java");
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
public class ConfigMapDependentResource
extends CRUDKubernetesDependentResource<ConfigMap, {{artifactClassId}}CustomResource> {

public static final String KEY = "key";

public ConfigMapDependentResource() {
super(ConfigMap.class);
}
Expand All @@ -28,7 +30,7 @@ protected ConfigMap desired({{artifactClassId}}CustomResource primary,
.withName(primary.getMetadata().getName())
.withNamespace(primary.getMetadata().getNamespace())
.build())
.withData(Map.of("data", primary.getSpec().getValue()))
.withData(Map.of(KEY, primary.getSpec().getValue()))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package {{groupId}};

import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import static {{groupId}}.ConfigMapDependentResource.KEY;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;

class {{artifactClassId}}ReconcilerIntegrationTest {

public static final String RESOURCE_NAME = "test1";
public static final String INITIAL_VALUE = "initial value";
public static final String CHANGED_VALUE = "changed value";

@RegisterExtension
LocallyRunOperatorExtension extension =
LocallyRunOperatorExtension.builder()
.withReconciler({{artifactClassId}}Reconciler.class)
.build();

@Test
void testCRUDOperations() {
var cr = extension.create(testResource());

await().untilAsserted(() -> {
var cm = extension.get(ConfigMap.class, RESOURCE_NAME);
assertThat(cm).isNotNull();
assertThat(cm.getData()).containsEntry(KEY, INITIAL_VALUE);
});

cr.getSpec().setValue(CHANGED_VALUE);
cr = extension.replace(cr);

await().untilAsserted(() -> {
var cm = extension.get(ConfigMap.class, RESOURCE_NAME);
assertThat(cm.getData()).containsEntry(KEY, CHANGED_VALUE);
});

extension.delete(cr);

await().untilAsserted(() -> {
var cm = extension.get(ConfigMap.class, RESOURCE_NAME);
assertThat(cm).isNull();
});
}

{{artifactClassId}}CustomResource testResource() {
var resource = new {{artifactClassId}}CustomResource();
resource.setMetadata(new ObjectMetaBuilder()
.withName(RESOURCE_NAME)
.build());
resource.setSpec(new {{artifactClassId}}Spec());
resource.getSpec().setValue(INITIAL_VALUE);
return resource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
<artifactId>operator-framework</artifactId>
<version>${josdk.version}</version>
</dependency>
<dependency>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>operator-framework-junit-5</artifactId>
<version>${josdk.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>crd-generator-apt</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void copiesFilesToTarget() {
private void assertProjectCompiles() {
try {
var process = Runtime.getRuntime()
.exec("mvn clean install -f target/test-project/pom.xml");
.exec("mvn clean install -f target/test-project/pom.xml -DskipTests");

BufferedReader stdOut = new BufferedReader(new InputStreamReader(process.getInputStream()));

Expand Down
2 changes: 1 addition & 1 deletion caffeine-bounded-cache-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>java-operator-sdk</artifactId>
<groupId>io.javaoperatorsdk</groupId>
<version>4.6.2-SNAPSHOT</version>
<version>4.7.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
10 changes: 10 additions & 0 deletions docs/documentation/dependent-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,16 @@ also be created, one per dependent resource.
See [integration test](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/ExternalStateBulkIT.java)
as a sample.


## GenericKubernetesResource based Dependent Resources

In rare circumstances resource handling where there is no class representation or just typeless handling might be needed.
Fabric8 Client provides [GenericKubernetesResource](https://github.com/fabric8io/kubernetes-client/blob/main/doc/CHEATSHEET.md#resource-typeless-api)
to support that.

For dependent resource this is supported by [GenericKubernetesDependentResource](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesDependentResource.java#L8-L8)
. See samples [here](https://github.com/java-operator-sdk/java-operator-sdk/tree/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/generickubernetesresource).

## Other Dependent Resource Features

### Caching and Event Handling in [KubernetesDependentResource](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java)
Expand Down
2 changes: 1 addition & 1 deletion micrometer-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>java-operator-sdk</artifactId>
<groupId>io.javaoperatorsdk</groupId>
<version>4.6.2-SNAPSHOT</version>
<version>4.7.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,9 @@ private static String getScope(ResourceID resourceID) {
}

private static void addGVKTags(GroupVersionKind gvk, List<Tag> tags, boolean prefixed) {
addTagOmittingOnEmptyValue(GROUP, gvk.group, tags, prefixed);
addTag(VERSION, gvk.version, tags, prefixed);
addTag(KIND, gvk.kind, tags, prefixed);
addTagOmittingOnEmptyValue(GROUP, gvk.getGroup(), tags, prefixed);
addTag(VERSION, gvk.getVersion(), tags, prefixed);
addTag(KIND, gvk.getKind(), tags, prefixed);
}

private void incrementCounter(ResourceID id, String counterName, Map<String, Object> metadata,
Expand Down
2 changes: 1 addition & 1 deletion operator-framework-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>io.javaoperatorsdk</groupId>
<artifactId>operator-framework-bom</artifactId>
<version>4.6.2-SNAPSHOT</version>
<version>4.7.0-SNAPSHOT</version>
<name>Operator SDK - Bill of Materials</name>
<packaging>pom</packaging>
<description>Java SDK for implementing Kubernetes operators</description>
Expand Down
2 changes: 1 addition & 1 deletion operator-framework-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>java-operator-sdk</artifactId>
<version>4.6.2-SNAPSHOT</version>
<version>4.7.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.Optional;
import java.util.Set;

import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
import io.javaoperatorsdk.operator.ReconcilerUtils;
Expand All @@ -28,7 +29,11 @@ protected DefaultResourceConfiguration(Class<R> resourceClass,
OnUpdateFilter<? super R> onUpdateFilter, GenericFilter<? super R> genericFilter,
ItemStore<R> itemStore, Long informerListLimit) {
this.resourceClass = resourceClass;
this.resourceTypeName = ReconcilerUtils.getResourceTypeName(resourceClass);
this.resourceTypeName = resourceClass.isAssignableFrom(GenericKubernetesResource.class)
// in general this is irrelevant now for secondary resources it is used just by controller
// where GenericKubernetesResource now does not apply
? GenericKubernetesResource.class.getSimpleName()
: ReconcilerUtils.getResourceTypeName(resourceClass);
this.onAddFilter = onAddFilter;
this.onUpdateFilter = onUpdateFilter;
this.genericFilter = genericFilter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public static <T> void executeAndWaitForAllToComplete(Stream<T> stream,
// to find out any exceptions
f.get();
} catch (ExecutionException e) {
throw new OperatorException(e.getCause());
throw new OperatorException(e);
} catch (InterruptedException e) {
log.warn("Interrupted.", e);
Thread.currentThread().interrupt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import java.util.Optional;
import java.util.Set;

import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
import io.javaoperatorsdk.operator.api.config.DefaultResourceConfiguration;
import io.javaoperatorsdk.operator.api.config.ResourceConfiguration;
import io.javaoperatorsdk.operator.api.config.Utils;
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
import io.javaoperatorsdk.operator.processing.GroupVersionKind;
import io.javaoperatorsdk.operator.processing.event.source.PrimaryToSecondaryMapper;
import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper;
import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter;
Expand All @@ -30,9 +32,11 @@ class DefaultInformerConfiguration<R extends HasMetadata> extends
private final SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper;
private final boolean followControllerNamespaceChanges;
private final OnDeleteFilter<? super R> onDeleteFilter;
private final GroupVersionKind groupVersionKind;

protected DefaultInformerConfiguration(String labelSelector,
Class<R> resourceClass,
GroupVersionKind groupVersionKind,
PrimaryToSecondaryMapper<?> primaryToSecondaryMapper,
SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper,
Set<String> namespaces, boolean followControllerNamespaceChanges,
Expand All @@ -44,7 +48,7 @@ protected DefaultInformerConfiguration(String labelSelector,
super(resourceClass, namespaces, labelSelector, onAddFilter, onUpdateFilter, genericFilter,
itemStore, informerListLimit);
this.followControllerNamespaceChanges = followControllerNamespaceChanges;

this.groupVersionKind = groupVersionKind;
this.primaryToSecondaryMapper = primaryToSecondaryMapper;
this.secondaryToPrimaryMapper =
Objects.requireNonNullElse(secondaryToPrimaryMapper,
Expand Down Expand Up @@ -72,6 +76,10 @@ public Optional<OnDeleteFilter<? super R>> onDeleteFilter() {
public <P extends HasMetadata> PrimaryToSecondaryMapper<P> getPrimaryToSecondaryMapper() {
return (PrimaryToSecondaryMapper<P>) primaryToSecondaryMapper;
}

public Optional<GroupVersionKind> getGroupVersionKind() {
return Optional.ofNullable(groupVersionKind);
}
}

/**
Expand Down Expand Up @@ -109,14 +117,17 @@ public <P extends HasMetadata> PrimaryToSecondaryMapper<P> getPrimaryToSecondary

<P extends HasMetadata> PrimaryToSecondaryMapper<P> getPrimaryToSecondaryMapper();

Optional<GroupVersionKind> getGroupVersionKind();

@SuppressWarnings("unused")
class InformerConfigurationBuilder<R extends HasMetadata> {

private final Class<R> resourceClass;
private final GroupVersionKind groupVersionKind;
private PrimaryToSecondaryMapper<?> primaryToSecondaryMapper;
private SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper;
private Set<String> namespaces;
private String labelSelector;
private final Class<R> resourceClass;
private OnAddFilter<? super R> onAddFilter;
private OnUpdateFilter<? super R> onUpdateFilter;
private OnDeleteFilter<? super R> onDeleteFilter;
Expand All @@ -127,6 +138,13 @@ class InformerConfigurationBuilder<R extends HasMetadata> {

private InformerConfigurationBuilder(Class<R> resourceClass) {
this.resourceClass = resourceClass;
this.groupVersionKind = null;
}

@SuppressWarnings("unchecked")
private InformerConfigurationBuilder(GroupVersionKind groupVersionKind) {
this.resourceClass = (Class<R>) GenericKubernetesResource.class;
this.groupVersionKind = groupVersionKind;
}

public <P extends HasMetadata> InformerConfigurationBuilder<R> withPrimaryToSecondaryMapper(
Expand Down Expand Up @@ -244,7 +262,7 @@ public InformerConfigurationBuilder<R> withInformerListLimit(Long informerListLi
}

public InformerConfiguration<R> build() {
return new DefaultInformerConfiguration<>(labelSelector, resourceClass,
return new DefaultInformerConfiguration<>(labelSelector, resourceClass, groupVersionKind,
primaryToSecondaryMapper,
secondaryToPrimaryMapper,
namespaces, inheritControllerNamespacesOnChange, onAddFilter, onUpdateFilter,
Expand All @@ -257,6 +275,14 @@ static <R extends HasMetadata> InformerConfigurationBuilder<R> from(
return new InformerConfigurationBuilder<>(resourceClass);
}

/**
* * For the case when want to use {@link GenericKubernetesResource}
*/
static <R extends HasMetadata> InformerConfigurationBuilder<R> from(
GroupVersionKind groupVersionKind) {
return new InformerConfigurationBuilder<>(groupVersionKind);
}

/**
* Creates a configuration builder that inherits namespaces from the controller and follows
* namespaces changes.
Expand All @@ -272,6 +298,16 @@ static <R extends HasMetadata> InformerConfigurationBuilder<R> from(
.withNamespacesInheritedFromController(eventSourceContext);
}

/**
* * For the case when want to use {@link GenericKubernetesResource}
*/
@SuppressWarnings("unchecked")
static InformerConfigurationBuilder<GenericKubernetesResource> from(
GroupVersionKind groupVersionKind, EventSourceContext<?> eventSourceContext) {
return new InformerConfigurationBuilder<GenericKubernetesResource>(groupVersionKind)
.withNamespacesInheritedFromController(eventSourceContext);
}

@SuppressWarnings("unchecked")
@Override
default Class<R> getResourceClass() {
Expand Down
Loading

0 comments on commit 621120f

Please sign in to comment.