Skip to content
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

improve: mapping from annotation depends on type #2606

Merged
merged 5 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ public static GroupVersionKind fromString(String gvk) {
}
}

/**
* Reverse to {@link #fromString(String)}.
*
* @return gvk encoded in simple string.
*/
public String toSimpleString() {
var res = "";
if (group != null) {
res += group + "/";
}
return res + version + "/" + kind;
}

public String getGroup() {
return group;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.javaoperatorsdk.operator.api.reconciler.Ignore;
import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected;
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ConfiguredDependentResource;
import io.javaoperatorsdk.operator.processing.GroupVersionKind;
import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource;
import io.javaoperatorsdk.operator.processing.dependent.Matcher.Result;
import io.javaoperatorsdk.operator.processing.event.ResourceID;
Expand Down Expand Up @@ -208,17 +209,18 @@ private boolean useNonOwnerRefBasedSecondaryToPrimaryMapping() {

protected void addSecondaryToPrimaryMapperAnnotations(R desired, P primary) {
addSecondaryToPrimaryMapperAnnotations(desired, primary, Mappers.DEFAULT_ANNOTATION_FOR_NAME,
Mappers.DEFAULT_ANNOTATION_FOR_NAMESPACE);
Mappers.DEFAULT_ANNOTATION_FOR_NAMESPACE, Mappers.DEFAULT_ANNOTATION_FOR_PRIMARY_TYPE);
}

protected void addSecondaryToPrimaryMapperAnnotations(R desired, P primary, String nameKey,
String namespaceKey) {
String namespaceKey, String typeKey) {
var annotations = desired.getMetadata().getAnnotations();
annotations.put(nameKey, primary.getMetadata().getName());
var primaryNamespaces = primary.getMetadata().getNamespace();
if (primaryNamespaces != null) {
annotations.put(namespaceKey, primary.getMetadata().getNamespace());
}
annotations.put(typeKey, GroupVersionKind.gvkFor(primary.getClass()).toSimpleString());
}

@Override
Expand Down Expand Up @@ -274,7 +276,7 @@ protected Optional<SecondaryToPrimaryMapper<R>> getSecondaryToPrimaryMapper(
return Optional
.of(Mappers.fromOwnerReferences(context.getPrimaryResourceClass(), clustered));
} else if (isCreatable()) {
return Optional.of(Mappers.fromDefaultAnnotations());
return Optional.of(Mappers.fromDefaultAnnotations(context.getPrimaryResourceClass()));
}
}
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.stream.Collectors;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.processing.GroupVersionKind;
import io.javaoperatorsdk.operator.processing.event.ResourceID;
import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper;

Expand All @@ -13,33 +14,42 @@ public class Mappers {
public static final String DEFAULT_ANNOTATION_FOR_NAME = "io.javaoperatorsdk/primary-name";
public static final String DEFAULT_ANNOTATION_FOR_NAMESPACE =
"io.javaoperatorsdk/primary-namespace";
public static final String DEFAULT_ANNOTATION_FOR_PRIMARY_TYPE =
"io.javaoperatorsdk/primary-type";

private Mappers() {}

public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromAnnotation(
String nameKey) {
return fromMetadata(nameKey, null, false);
String nameKey, String typeKey, Class<? extends HasMetadata> primaryResourceType) {
return fromMetadata(nameKey, null, typeKey, primaryResourceType, false);
}

@SuppressWarnings("unused")
public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromAnnotation(
String nameKey, String namespaceKey) {
return fromMetadata(nameKey, namespaceKey, false);
String nameKey, String namespaceKey, String typeKey,
Class<? extends HasMetadata> primaryResourceType) {
return fromMetadata(nameKey, namespaceKey, typeKey, primaryResourceType, false);
}

@SuppressWarnings("unused")
public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromLabel(String nameKey) {
return fromMetadata(nameKey, null, true);
public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromLabel(String nameKey,
String typeKey,
Class<? extends HasMetadata> primaryResourceType) {
return fromMetadata(nameKey, null, typeKey, primaryResourceType, true);
}

public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromDefaultAnnotations() {
return fromMetadata(DEFAULT_ANNOTATION_FOR_NAME, DEFAULT_ANNOTATION_FOR_NAMESPACE, false);
public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromDefaultAnnotations(
Class<? extends HasMetadata> primaryResourceType) {
return fromMetadata(DEFAULT_ANNOTATION_FOR_NAME, DEFAULT_ANNOTATION_FOR_NAMESPACE,
DEFAULT_ANNOTATION_FOR_PRIMARY_TYPE,
primaryResourceType, false);
}

@SuppressWarnings("unused")
public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromLabel(
String nameKey, String namespaceKey) {
return fromMetadata(nameKey, namespaceKey, true);
String nameKey, String namespaceKey, String typeKey,
Class<? extends HasMetadata> primaryResourceType) {
return fromMetadata(nameKey, namespaceKey, typeKey, primaryResourceType, true);
}

public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromOwnerReferences(
Expand Down Expand Up @@ -78,7 +88,8 @@ public static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromOwnerRefer
}

private static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromMetadata(
String nameKey, String namespaceKey, boolean isLabel) {
String nameKey, String namespaceKey, String typeKey,
Class<? extends HasMetadata> primaryResourceType, boolean isLabel) {
return resource -> {
final var metadata = resource.getMetadata();
if (metadata == null) {
Expand All @@ -94,6 +105,15 @@ private static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromMetadata(
}
var namespace =
namespaceKey == null ? resource.getMetadata().getNamespace() : map.get(namespaceKey);

String gvkSimple = map.get(typeKey);

if (gvkSimple != null &&
!GroupVersionKind.fromString(gvkSimple)
.equals(GroupVersionKind.gvkFor(primaryResourceType))) {
return Set.of();
}

return Set.of(new ResourceID(name, namespace));
}
};
Expand Down Expand Up @@ -139,9 +159,17 @@ public static <OWNER extends HasMetadata, T extends HasMetadata> SecondaryToPrim

public static class SecondaryToPrimaryFromDefaultAnnotation
implements SecondaryToPrimaryMapper<HasMetadata> {

private Class<? extends HasMetadata> primaryResourceType;

public SecondaryToPrimaryFromDefaultAnnotation(
Class<? extends HasMetadata> primaryResourceType) {
this.primaryResourceType = primaryResourceType;
}

@Override
public Set<ResourceID> toPrimaryResourceIDs(HasMetadata resource) {
return Mappers.fromDefaultAnnotations().toPrimaryResourceIDs(resource);
return Mappers.fromDefaultAnnotations(primaryResourceType).toPrimaryResourceIDs(resource);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,13 @@ void pluralShouldOverrideDefaultComputedVersionIfProvided() {
"MyPlural");
assertThat(gvk.getPlural()).hasValue("MyPlural");
}

@Test
void encodesGVKToSimpleString() {
var gvk = GroupVersionKind.fromString("apps/v1/Deployment");
assertThat(gvk.toSimpleString()).isEqualTo("apps/v1/Deployment");

gvk = GroupVersionKind.fromString("v1/ConfigMap");
assertThat(gvk.toSimpleString()).isEqualTo("v1/ConfigMap");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class InformerEventSourceTestCustomReconciler
LoggerFactory.getLogger(InformerEventSourceTestCustomReconciler.class);

public static final String RELATED_RESOURCE_NAME = "relatedResourceName";
public static final String RELATED_RESOURCE_TYPE = "relatedResourceType";
public static final String TARGET_CONFIG_MAP_KEY = "targetStatus";
public static final String MISSING_CONFIG_MAP = "Missing Config Map";

Expand All @@ -38,7 +39,9 @@ public List<EventSource<?, InformerEventSourceTestCustomResource>> prepareEventS
InformerEventSourceConfiguration<ConfigMap> config =
InformerEventSourceConfiguration
.from(ConfigMap.class, InformerEventSourceTestCustomResource.class)
.withSecondaryToPrimaryMapper(Mappers.fromAnnotation(RELATED_RESOURCE_NAME))
.withSecondaryToPrimaryMapper(
Mappers.fromAnnotation(RELATED_RESOURCE_NAME, RELATED_RESOURCE_TYPE,
InformerEventSourceTestCustomResource.class))
.build();

return List.of(new InformerEventSource<>(config, context));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public List<EventSource<?, InformerRemoteClusterCustomResource>> prepareEventSou
.from(ConfigMap.class, InformerRemoteClusterCustomResource.class)
// owner references do not work cross cluster, using
// annotations here to reference primary resource
.withSecondaryToPrimaryMapper(Mappers.fromDefaultAnnotations())
.withSecondaryToPrimaryMapper(
Mappers.fromDefaultAnnotations(InformerRemoteClusterCustomResource.class))
// setting remote client for informer
.withKubernetesClient(remoteClient)
.withInformerConfiguration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ public class CustomMappingConfigMapDependentResource

public static final String CUSTOM_NAME_KEY = "customNameKey";
public static final String CUSTOM_NAMESPACE_KEY = "customNamespaceKey";
public static final String CUSTOM_TYPE_KEY = "customTypeKey";
public static final String KEY = "key";

private static final SecondaryToPrimaryMapper<ConfigMap> mapper =
Mappers.fromAnnotation(CUSTOM_NAME_KEY, CUSTOM_NAMESPACE_KEY);
Mappers.fromAnnotation(CUSTOM_NAME_KEY, CUSTOM_NAMESPACE_KEY, CUSTOM_TYPE_KEY,
DependentCustomMappingCustomResource.class);

public CustomMappingConfigMapDependentResource() {
super(ConfigMap.class);
Expand All @@ -44,7 +46,8 @@ protected ConfigMap desired(DependentCustomMappingCustomResource primary,
@Override
protected void addSecondaryToPrimaryMapperAnnotations(ConfigMap desired,
DependentCustomMappingCustomResource primary) {
addSecondaryToPrimaryMapperAnnotations(desired, primary, CUSTOM_NAME_KEY, CUSTOM_NAMESPACE_KEY);
addSecondaryToPrimaryMapperAnnotations(desired, primary, CUSTOM_NAME_KEY, CUSTOM_NAMESPACE_KEY,
CUSTOM_TYPE_KEY);
}


Expand Down