Skip to content

Commit e971c4d

Browse files
authored
feat: remove primary to secondary mapper (handled automatically) (#1161)
1 parent 794f9cf commit e971c4d

File tree

35 files changed

+508
-163
lines changed

35 files changed

+508
-163
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,54 +8,41 @@
88
import io.javaoperatorsdk.operator.api.config.DefaultResourceConfiguration;
99
import io.javaoperatorsdk.operator.api.config.ResourceConfiguration;
1010
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
11-
import io.javaoperatorsdk.operator.processing.event.ResourceID;
12-
import io.javaoperatorsdk.operator.processing.event.source.PrimaryToSecondaryMapper;
1311
import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper;
1412
import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers;
1513

1614
@SuppressWarnings("rawtypes")
17-
public interface InformerConfiguration<R extends HasMetadata, P extends HasMetadata>
15+
public interface InformerConfiguration<R extends HasMetadata>
1816
extends ResourceConfiguration<R> {
1917

20-
class DefaultInformerConfiguration<R extends HasMetadata, P extends HasMetadata> extends
21-
DefaultResourceConfiguration<R> implements InformerConfiguration<R, P> {
18+
class DefaultInformerConfiguration<R extends HasMetadata> extends
19+
DefaultResourceConfiguration<R> implements InformerConfiguration<R> {
2220

2321
private final SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper;
24-
private final PrimaryToSecondaryMapper<P> primaryToSecondaryMapper;
2522

2623
protected DefaultInformerConfiguration(String labelSelector,
2724
Class<R> resourceClass,
2825
SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper,
29-
PrimaryToSecondaryMapper<P> primaryToSecondaryMapper,
3026
Set<String> namespaces) {
3127
super(labelSelector, resourceClass, namespaces);
3228
this.secondaryToPrimaryMapper =
3329
Objects.requireNonNullElse(secondaryToPrimaryMapper,
3430
Mappers.fromOwnerReference());
35-
this.primaryToSecondaryMapper =
36-
Objects.requireNonNullElseGet(primaryToSecondaryMapper, () -> ResourceID::fromResource);
3731
}
3832

3933

4034
public SecondaryToPrimaryMapper<R> getSecondaryToPrimaryMapper() {
4135
return secondaryToPrimaryMapper;
4236
}
4337

44-
public PrimaryToSecondaryMapper<P> getPrimaryToSecondaryMapper() {
45-
return primaryToSecondaryMapper;
46-
}
47-
4838
}
4939

5040
SecondaryToPrimaryMapper<R> getSecondaryToPrimaryMapper();
5141

52-
PrimaryToSecondaryMapper<P> getPrimaryToSecondaryMapper();
53-
5442
@SuppressWarnings("unused")
5543
class InformerConfigurationBuilder<R extends HasMetadata, P extends HasMetadata> {
5644

57-
private SecondaryToPrimaryMapper<R> secondaryToPrimaryResourcesIdSet;
58-
private PrimaryToSecondaryMapper<P> associatedWith;
45+
private SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper;
5946
private Set<String> namespaces;
6047
private String labelSelector;
6148
private final Class<R> resourceClass;
@@ -66,17 +53,10 @@ private InformerConfigurationBuilder(Class<R> resourceClass) {
6653

6754
public InformerConfigurationBuilder<R, P> withSecondaryToPrimaryMapper(
6855
SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper) {
69-
this.secondaryToPrimaryResourcesIdSet = secondaryToPrimaryMapper;
56+
this.secondaryToPrimaryMapper = secondaryToPrimaryMapper;
7057
return this;
7158
}
7259

73-
public InformerConfigurationBuilder<R, P> withPrimaryToSecondaryMapper(
74-
PrimaryToSecondaryMapper<P> associatedWith) {
75-
this.associatedWith = associatedWith;
76-
return this;
77-
}
78-
79-
8060
public InformerConfigurationBuilder<R, P> withNamespaces(String... namespaces) {
8161
this.namespaces = namespaces != null ? Set.of(namespaces) : Collections.emptySet();
8262
return this;
@@ -93,9 +73,9 @@ public InformerConfigurationBuilder<R, P> withLabelSelector(String labelSelector
9373
return this;
9474
}
9575

96-
public InformerConfiguration<R, P> build() {
76+
public InformerConfiguration<R> build() {
9777
return new DefaultInformerConfiguration<>(labelSelector, resourceClass,
98-
secondaryToPrimaryResourcesIdSet, associatedWith,
78+
secondaryToPrimaryMapper,
9979
namespaces);
10080
}
10181
}
@@ -111,12 +91,10 @@ static InformerConfigurationBuilder from(Class resourceClass) {
11191
}
11292

11393
static <R extends HasMetadata, P extends HasMetadata> InformerConfigurationBuilder<R, P> from(
114-
InformerConfiguration<R, P> configuration) {
94+
InformerConfiguration<R> configuration) {
11595
return new InformerConfigurationBuilder<R, P>(configuration.getResourceClass())
11696
.withNamespaces(configuration.getNamespaces())
11797
.withLabelSelector(configuration.getLabelSelector())
118-
.withPrimaryToSecondaryMapper(
119-
configuration.getPrimaryToSecondaryMapper())
12098
.withSecondaryToPrimaryMapper(configuration.getSecondaryToPrimaryMapper());
12199
}
122100
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.javaoperatorsdk.operator.api.reconciler;
22

33
import java.util.Optional;
4+
import java.util.Set;
45

56
import io.fabric8.kubernetes.api.model.HasMetadata;
67
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
@@ -14,6 +15,8 @@ default <T> Optional<T> getSecondaryResource(Class<T> expectedType) {
1415
return getSecondaryResource(expectedType, null);
1516
}
1617

18+
<T> Set<T> getSecondaryResources(Class<T> expectedType);
19+
1720
<T> Optional<T> getSecondaryResource(Class<T> expectedType, String eventSourceName);
1821

1922
ControllerConfiguration<P> getControllerConfiguration();

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package io.javaoperatorsdk.operator.api.reconciler;
22

3+
import java.util.Collections;
4+
import java.util.List;
35
import java.util.Optional;
6+
import java.util.Set;
7+
import java.util.stream.Collectors;
48

59
import io.fabric8.kubernetes.api.model.HasMetadata;
610
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
711
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedDependentResourceContext;
812
import io.javaoperatorsdk.operator.processing.Controller;
13+
import io.javaoperatorsdk.operator.processing.MultiResourceOwner;
914

1015
public class DefaultContext<P extends HasMetadata> implements Context<P> {
1116

@@ -28,9 +33,28 @@ public Optional<RetryInfo> getRetryInfo() {
2833
return Optional.ofNullable(retryInfo);
2934
}
3035

36+
@Override
37+
@SuppressWarnings("unchecked")
38+
public <T> Set<T> getSecondaryResources(Class<T> expectedType) {
39+
return controller.getEventSourceManager().getEventSourcesFor(expectedType).stream()
40+
.map(
41+
es -> {
42+
if (es instanceof MultiResourceOwner) {
43+
return ((MultiResourceOwner<T, P>) es).getSecondaryResources(primaryResource);
44+
} else {
45+
return es.getSecondaryResource(primaryResource)
46+
.map(List::of)
47+
.orElse(Collections.emptyList());
48+
}
49+
})
50+
.flatMap(List::stream)
51+
.collect(Collectors.toSet());
52+
}
53+
3154
@Override
3255
public <T> Optional<T> getSecondaryResource(Class<T> expectedType, String eventSourceName) {
33-
return controller.getEventSourceManager()
56+
return controller
57+
.getEventSourceManager()
3458
.getResourceEventSourceFor(expectedType, eventSourceName)
3559
.getSecondaryResource(primaryResource);
3660
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.javaoperatorsdk.operator.processing;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
6+
import io.fabric8.kubernetes.api.model.HasMetadata;
7+
8+
public interface MultiResourceOwner<R, P extends HasMetadata> extends ResourceOwner<R, P> {
9+
10+
default Optional<R> getSecondaryResource(P primary) {
11+
var list = getSecondaryResources(primary);
12+
if (list.isEmpty()) {
13+
return Optional.empty();
14+
} else if (list.size() == 1) {
15+
return Optional.of(list.get(0));
16+
} else {
17+
throw new IllegalStateException("More than 1 secondary resource related to primary");
18+
}
19+
20+
}
21+
22+
List<R> getSecondaryResources(P primary);
23+
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
public abstract class AbstractEventSourceHolderDependentResource<R, P extends HasMetadata, T extends ResourceEventSource<R, P>>
1212
extends AbstractDependentResource<R, P>
1313
implements EventSourceProvider<P> {
14+
1415
private T eventSource;
1516
private boolean isCacheFillerEventSource;
1617

@@ -48,7 +49,6 @@ protected void onUpdated(ResourceID primaryResourceId, R updated, R actual) {
4849
}
4950
}
5051

51-
5252
@SuppressWarnings("unchecked")
5353
private RecentOperationCacheFiller<R> recentOperationCacheFiller() {
5454
return (RecentOperationCacheFiller<R>) eventSource;

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import io.javaoperatorsdk.operator.processing.dependent.Matcher;
2121
import io.javaoperatorsdk.operator.processing.dependent.Matcher.Result;
2222
import io.javaoperatorsdk.operator.processing.event.ResourceID;
23-
import io.javaoperatorsdk.operator.processing.event.source.PrimaryToSecondaryMapper;
2423
import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper;
2524
import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
2625
import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers;
@@ -58,16 +57,11 @@ private void configureWith(String labelSelector, Set<String> namespaces) {
5857
final var primaryResourcesRetriever =
5958
(this instanceof SecondaryToPrimaryMapper) ? (SecondaryToPrimaryMapper<R>) this
6059
: Mappers.fromOwnerReference();
61-
final PrimaryToSecondaryMapper<P> secondaryResourceIdentifier =
62-
(this instanceof PrimaryToSecondaryMapper)
63-
? (PrimaryToSecondaryMapper<P>) this
64-
: ResourceID::fromResource;
65-
InformerConfiguration<R, P> ic =
60+
InformerConfiguration<R> ic =
6661
InformerConfiguration.from(resourceType())
6762
.withLabelSelector(labelSelector)
6863
.withNamespaces(namespaces)
6964
.withSecondaryToPrimaryMapper(primaryResourcesRetriever)
70-
.withPrimaryToSecondaryMapper(secondaryResourceIdentifier)
7165
.build();
7266
configureWith(new InformerEventSource<>(ic, client));
7367
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.javaoperatorsdk.operator.processing.event;
22

33
import java.util.LinkedHashSet;
4+
import java.util.List;
45
import java.util.Objects;
56
import java.util.Set;
67
import java.util.concurrent.locks.ReentrantLock;
@@ -176,6 +177,10 @@ <S> ResourceEventSource<S, R> getResourceEventSourceFor(
176177
return getResourceEventSourceFor(dependentType, null);
177178
}
178179

180+
public <S> List<ResourceEventSource<S, R>> getEventSourcesFor(Class<S> dependentType) {
181+
return eventSources.getEventSources(dependentType);
182+
}
183+
179184
public <S> ResourceEventSource<S, R> getResourceEventSourceFor(
180185
Class<S> dependentType, String qualifier) {
181186
Objects.requireNonNull(dependentType, "dependentType is Mandatory");

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSources.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package io.javaoperatorsdk.operator.processing.event;
22

3-
import java.util.HashMap;
4-
import java.util.Iterator;
5-
import java.util.Map;
3+
import java.util.*;
64
import java.util.concurrent.ConcurrentNavigableMap;
75
import java.util.concurrent.ConcurrentSkipListMap;
6+
import java.util.stream.Collectors;
87
import java.util.stream.Stream;
98

109
import io.fabric8.kubernetes.api.model.HasMetadata;
@@ -131,4 +130,13 @@ private String keyAsString(Class dependentType, String name) {
131130
? "(" + dependentType.getName() + ", " + name + ")"
132131
: dependentType.getName();
133132
}
133+
134+
@SuppressWarnings("unchecked")
135+
public <S> List<ResourceEventSource<S, R>> getEventSources(Class<S> dependentType) {
136+
final var sourcesForType = sources.get(keyFor(dependentType));
137+
return sourcesForType.values().stream()
138+
.filter(ResourceEventSource.class::isInstance)
139+
.map(es -> (ResourceEventSource<S, R>) es)
140+
.collect(Collectors.toList());
141+
}
134142
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ExternalResourceCachingEventSource.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.javaoperatorsdk.operator.processing.event;
22

3+
import java.util.Optional;
4+
35
import io.fabric8.kubernetes.api.model.HasMetadata;
46
import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller;
57
import io.javaoperatorsdk.operator.processing.event.source.CachingEventSource;
@@ -50,4 +52,9 @@ public synchronized void handleRecentResourceUpdate(ResourceID resourceID, R res
5052
}
5153
});
5254
}
55+
56+
@Override
57+
public Optional<R> getSecondaryResource(P primary) {
58+
return cache.get(ResourceID.fromResource(primary));
59+
}
5360
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CachingEventSource.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,4 @@ public Optional<R> getCachedValue(ResourceID resourceID) {
5151
return cache.get(resourceID);
5252
}
5353

54-
@Override
55-
public Optional<R> getSecondaryResource(P primary) {
56-
return cache.get(ResourceID.fromResource(primary));
57-
}
58-
5954
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/PrimaryToSecondaryMapper.java

Lines changed: 0 additions & 9 deletions
This file was deleted.

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/SecondaryToPrimaryMapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
import io.javaoperatorsdk.operator.processing.event.ResourceID;
66

77
@FunctionalInterface
8-
public interface SecondaryToPrimaryMapper<T> {
9-
Set<ResourceID> toPrimaryResourceIDs(T dependentResource);
8+
public interface SecondaryToPrimaryMapper<R> {
9+
Set<ResourceID> toPrimaryResourceIDs(R dependentResource);
1010
}

0 commit comments

Comments
 (0)