Skip to content

Commit 0c6c0b2

Browse files
committed
wip
Signed-off-by: Attila Mészáros <[email protected]>
1 parent 21789ee commit 0c6c0b2

File tree

7 files changed

+146
-7
lines changed

7 files changed

+146
-7
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ public interface ComplementaryPrimaryToSecondaryIndex<R extends HasMetadata> {
1111

1212
void cleanupForResource(R resourceID);
1313

14-
Set<ResourceID> getComplementarySecondaryResources(ResourceID primary);
14+
Set<ResourceID> getSecondaryResources(ResourceID primary);
1515
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void cleanupForResource(R resource) {
5050
}
5151

5252
@Override
53-
public Set<ResourceID> getComplementarySecondaryResources(ResourceID primary) {
53+
public Set<ResourceID> getSecondaryResources(ResourceID primary) {
5454
var resourceIDs = index.get(primary);
5555
if (resourceIDs == null) {
5656
return Collections.emptySet();

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ private InformerEventSource(
9898
parseResourceVersions);
9999
// If there is a primary to secondary mapper there is no need for primary to secondary index.
100100
primaryToSecondaryMapper = configuration.getPrimaryToSecondaryMapper();
101-
if (primaryToSecondaryMapper == null) {
101+
if (useSecondaryToPrimaryIndex()) {
102102
complementaryPrimaryToSecondaryIndex =
103103
new DefaultComplementaryPrimaryToSecondaryIndex<>(
104104
configuration.getSecondaryToPrimaryMapper());
@@ -264,8 +264,7 @@ public Set<R> getSecondaryResources(P primary) {
264264
primary.getMetadata().getName(),
265265
primary.getMetadata().getNamespace(),
266266
resources.size());
267-
var complementaryIds =
268-
complementaryPrimaryToSecondaryIndex.getComplementarySecondaryResources(primaryID);
267+
var complementaryIds = complementaryPrimaryToSecondaryIndex.getSecondaryResources(primaryID);
269268
var res =
270269
resources.stream()
271270
.map(

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public void explicitAdd(R resource) {}
1515
public void cleanupForResource(R resourceID) {}
1616

1717
@Override
18-
public Set<ResourceID> getComplementarySecondaryResources(ResourceID primary) {
18+
public Set<ResourceID> getSecondaryResources(ResourceID primary) {
1919
return Set.of();
2020
}
2121
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package io.javaoperatorsdk.operator.processing.event.source.informer;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.temporal.ChronoUnit;
5+
import java.util.Set;
6+
7+
import org.junit.jupiter.api.BeforeEach;
8+
import org.junit.jupiter.api.Test;
9+
10+
import io.fabric8.kubernetes.api.model.ConfigMap;
11+
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
12+
import io.fabric8.kubernetes.api.model.HasMetadata;
13+
import io.fabric8.kubernetes.api.model.ObjectMeta;
14+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
15+
import io.javaoperatorsdk.operator.processing.event.ResourceID;
16+
import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.mockito.ArgumentMatchers.any;
20+
import static org.mockito.Mockito.mock;
21+
import static org.mockito.Mockito.when;
22+
23+
class DefaultComplementaryPrimaryToSecondaryIndexTest {
24+
25+
@SuppressWarnings("unchecked")
26+
private final SecondaryToPrimaryMapper<ConfigMap> secondaryToPrimaryMapperMock =
27+
mock(SecondaryToPrimaryMapper.class);
28+
29+
private final DefaultComplementaryPrimaryToSecondaryIndex<ConfigMap> primaryToSecondaryIndex =
30+
new DefaultComplementaryPrimaryToSecondaryIndex<>(secondaryToPrimaryMapperMock);
31+
32+
private final ResourceID primaryID1 = new ResourceID("id1", "default");
33+
private final ResourceID primaryID2 = new ResourceID("id2", "default");
34+
private final ConfigMap secondary1 = secondary("secondary1");
35+
private final ConfigMap secondary2 = secondary("secondary2");
36+
37+
@BeforeEach
38+
void setup() {
39+
when(secondaryToPrimaryMapperMock.toPrimaryResourceIDs(any()))
40+
.thenReturn(Set.of(primaryID1, primaryID2));
41+
}
42+
43+
@Test
44+
void returnsEmptySetOnEmptyIndex() {
45+
var res = primaryToSecondaryIndex.getSecondaryResources(ResourceID.fromResource(secondary1));
46+
assertThat(res).isEmpty();
47+
}
48+
49+
@Test
50+
void indexesNewResources() {
51+
primaryToSecondaryIndex.explicitAdd(secondary1);
52+
53+
var secondaryResources1 = primaryToSecondaryIndex.getSecondaryResources(primaryID1);
54+
var secondaryResources2 = primaryToSecondaryIndex.getSecondaryResources(primaryID2);
55+
56+
assertThat(secondaryResources1).containsOnly(ResourceID.fromResource(secondary1));
57+
assertThat(secondaryResources2).containsOnly(ResourceID.fromResource(secondary1));
58+
}
59+
60+
@Test
61+
void indexesAdditionalResources() {
62+
primaryToSecondaryIndex.explicitAdd(secondary1);
63+
primaryToSecondaryIndex.explicitAdd(secondary2);
64+
65+
var secondaryResources1 = primaryToSecondaryIndex.getSecondaryResources(primaryID1);
66+
var secondaryResources2 = primaryToSecondaryIndex.getSecondaryResources(primaryID2);
67+
68+
assertThat(secondaryResources1)
69+
.containsOnly(ResourceID.fromResource(secondary1), ResourceID.fromResource(secondary2));
70+
assertThat(secondaryResources2)
71+
.containsOnly(ResourceID.fromResource(secondary1), ResourceID.fromResource(secondary2));
72+
}
73+
74+
@Test
75+
void removingResourceFromIndex() {
76+
primaryToSecondaryIndex.explicitAdd(secondary1);
77+
primaryToSecondaryIndex.explicitAdd(secondary2);
78+
primaryToSecondaryIndex.cleanupForResource(secondary1);
79+
80+
var secondaryResources1 = primaryToSecondaryIndex.getSecondaryResources(primaryID1);
81+
var secondaryResources2 = primaryToSecondaryIndex.getSecondaryResources(primaryID2);
82+
83+
assertThat(secondaryResources1).containsOnly(ResourceID.fromResource(secondary2));
84+
assertThat(secondaryResources2).containsOnly(ResourceID.fromResource(secondary2));
85+
86+
primaryToSecondaryIndex.cleanupForResource(secondary2);
87+
88+
secondaryResources1 = primaryToSecondaryIndex.getSecondaryResources(primaryID1);
89+
secondaryResources2 = primaryToSecondaryIndex.getSecondaryResources(primaryID2);
90+
91+
assertThat(secondaryResources1).isEmpty();
92+
assertThat(secondaryResources2).isEmpty();
93+
}
94+
95+
@Test
96+
void testPerformance() {
97+
var primaryToSecondaryIndex =
98+
new DefaultComplementaryPrimaryToSecondaryIndex<>(
99+
new SecondaryToPrimaryMapper<HasMetadata>() {
100+
@Override
101+
public Set<ResourceID> toPrimaryResourceIDs(HasMetadata resource) {
102+
return Set.of(
103+
new ResourceID(
104+
resource.getMetadata().getName(), resource.getMetadata().getNamespace()));
105+
}
106+
});
107+
var start = LocalDateTime.now();
108+
for (int i = 0; i < 1_000_000; i++) {
109+
primaryToSecondaryIndex.explicitAdd(cm(i));
110+
}
111+
System.out.println(ChronoUnit.MILLIS.between(start, LocalDateTime.now()));
112+
113+
start = LocalDateTime.now();
114+
for (int i = 0; i < 1_000_000; i++) {
115+
primaryToSecondaryIndex.cleanupForResource(cm(i));
116+
}
117+
System.out.println(ChronoUnit.MILLIS.between(start, LocalDateTime.now()));
118+
System.out.println("ok");
119+
}
120+
121+
private static ConfigMap cm(int i) {
122+
return new ConfigMapBuilder()
123+
.withMetadata(new ObjectMetaBuilder().withName("test" + i).withNamespace("default").build())
124+
.build();
125+
}
126+
127+
ConfigMap secondary(String name) {
128+
ConfigMap configMap = new ConfigMap();
129+
configMap.setMetadata(new ObjectMeta());
130+
configMap.getMetadata().setName(name);
131+
configMap.getMetadata().setNamespace("default");
132+
return configMap;
133+
}
134+
}

operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/dependentresourcecrossref/DependentResourceCrossRefIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
class DependentResourceCrossRefIT {
1717

1818
public static final String TEST_RESOURCE_NAME = "test";
19-
public static final int EXECUTION_NUMBER = 150;
19+
public static final int EXECUTION_NUMBER = 250;
2020

2121
@RegisterExtension
2222
LocallyRunOperatorExtension operator =

operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/dependentresourcecrossref/DependentResourceCrossRefReconciler.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import java.util.Map;
66
import java.util.concurrent.atomic.AtomicInteger;
77

8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
811
import io.fabric8.kubernetes.api.model.ConfigMap;
912
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
1013
import io.fabric8.kubernetes.api.model.Secret;
@@ -26,6 +29,8 @@
2629
@ControllerConfiguration
2730
public class DependentResourceCrossRefReconciler
2831
implements Reconciler<DependentResourceCrossRefResource> {
32+
private static final Logger log =
33+
LoggerFactory.getLogger(DependentResourceCrossRefReconciler.class);
2934

3035
public static final String SECRET_NAME = "secret";
3136
private final AtomicInteger numberOfExecutions = new AtomicInteger(0);
@@ -48,6 +53,7 @@ public ErrorStatusUpdateControl<DependentResourceCrossRefResource> updateErrorSt
4853
DependentResourceCrossRefResource resource,
4954
Context<DependentResourceCrossRefResource> context,
5055
Exception e) {
56+
log.error("Status update on error", e);
5157
errorHappened = true;
5258
return ErrorStatusUpdateControl.noStatusUpdate();
5359
}

0 commit comments

Comments
 (0)