Skip to content

Commit 57428da

Browse files
csvirimetacosm
authored andcommitted
external resource
1 parent 714f42c commit 57428da

File tree

6 files changed

+199
-2
lines changed

6 files changed

+199
-2
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public AbstractDependentResource() {
4242
public ReconcileResult<R> reconcile(P primary, Context<P> context) {
4343
var count = bulk ? bulkDependentResource.count(primary, context) : 1;
4444
if (bulk) {
45-
deleteBulkResourcesIfRequired(count, resourceDiscriminator.size(), primary, context);
45+
deleteBulkResourcesIfRequired(count, lastKnownBulkSize(), primary, context);
4646
adjustDiscriminators(count);
4747
}
4848
ReconcileResult<R> result = new ReconcileResult<>();
@@ -222,4 +222,8 @@ public ResourceDiscriminator<R, P> getResourceDiscriminator() {
222222
}
223223
}
224224

225+
protected int lastKnownBulkSize() {
226+
return resourceDiscriminator.size();
227+
}
228+
225229
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.javaoperatorsdk.operator.processing.dependent;
2+
3+
import io.fabric8.kubernetes.api.model.HasMetadata;
4+
import io.javaoperatorsdk.operator.api.reconciler.Context;
5+
6+
public interface BulkUpdater<R, P extends HasMetadata> extends Updater<R, P> {
7+
8+
default Matcher.Result<R> match(R actualResource, P primary, Context<P> context) {
9+
throw new IllegalStateException();
10+
}
11+
12+
Matcher.Result<R> match(R actualResource, P primary, int index, Context<P> context);
13+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public Result<R> match(R actualResource, P primary, int index, Context<P> contex
140140

141141
public void delete(P primary, Context<P> context) {
142142
if (bulk) {
143-
deleteBulkResourcesIfRequired(0, resourceDiscriminator.size(), primary, context);
143+
deleteBulkResourcesIfRequired(0, lastKnownBulkSize(), primary, context);
144144
} else {
145145
var resource = getSecondaryResource(primary, context);
146146
resource.ifPresent(r -> client.resource(r).delete());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package io.javaoperatorsdk.operator.sample.bulkdependent.external;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Optional;
6+
import java.util.Set;
7+
import java.util.stream.Collectors;
8+
9+
import io.javaoperatorsdk.operator.api.reconciler.Context;
10+
import io.javaoperatorsdk.operator.processing.dependent.*;
11+
import io.javaoperatorsdk.operator.processing.dependent.external.PollingDependentResource;
12+
import io.javaoperatorsdk.operator.processing.event.ResourceID;
13+
import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper;
14+
import io.javaoperatorsdk.operator.sample.bulkdependent.BulkDependentTestCustomResource;
15+
16+
public class ExternalBulkDependentResource
17+
extends PollingDependentResource<ExternalResource, BulkDependentTestCustomResource>
18+
implements BulkDependentResource<ExternalResource, BulkDependentTestCustomResource>,
19+
BulkUpdater<ExternalResource, BulkDependentTestCustomResource> {
20+
21+
public static final String EXTERNAL_RESOURCE_NAME_DELIMITER = "#";
22+
23+
private ExternalServiceMock externalServiceMock = ExternalServiceMock.getInstance();
24+
25+
public ExternalBulkDependentResource() {
26+
super(ExternalResource.class, CacheKeyMapper.singleResourceCacheKeyMapper());
27+
}
28+
29+
@Override
30+
public Map<ResourceID, Set<ExternalResource>> fetchResources() {
31+
// todo
32+
Map<ResourceID, Set<ExternalResource>> result = new HashMap<>();
33+
var resources = externalServiceMock.listResources();
34+
35+
return result;
36+
}
37+
38+
@Override
39+
public void delete(BulkDependentTestCustomResource primary,
40+
Context<BulkDependentTestCustomResource> context) {
41+
deleteBulkResourcesIfRequired(0, lastKnownBulkSize(), primary, context);
42+
}
43+
44+
@Override
45+
public int count(BulkDependentTestCustomResource primary,
46+
Context<BulkDependentTestCustomResource> context) {
47+
return primary.getSpec().getNumberOfResources();
48+
}
49+
50+
@Override
51+
public void deleteBulkResourceWithIndex(BulkDependentTestCustomResource primary,
52+
ExternalResource resource, int i, Context<BulkDependentTestCustomResource> context) {
53+
externalServiceMock.delete(resource.getId());
54+
}
55+
56+
@Override
57+
public BulkResourceDiscriminatorFactory<ExternalResource, BulkDependentTestCustomResource> bulkResourceDiscriminatorFactory() {
58+
return index -> (resource, primary, context) -> {
59+
ExternalResource collect = context.getSecondaryResources(resource).stream()
60+
.filter(r -> r.getId().endsWith(EXTERNAL_RESOURCE_NAME_DELIMITER + index))
61+
.collect(Collectors.collectingAndThen(
62+
Collectors.toList(),
63+
list -> {
64+
if (list.size() > 1) {
65+
throw new IllegalStateException("Found more than 1 object: " + list);
66+
}
67+
return list.get(0);
68+
}));
69+
return Optional.ofNullable(collect);
70+
};
71+
}
72+
73+
@Override
74+
public ExternalResource desired(BulkDependentTestCustomResource primary, int index,
75+
Context<BulkDependentTestCustomResource> context) {
76+
return new ExternalResource(toExternalResourceId(primary, index), "" + index);
77+
}
78+
79+
@Override
80+
public ExternalResource create(ExternalResource desired, BulkDependentTestCustomResource primary,
81+
Context<BulkDependentTestCustomResource> context) {
82+
return externalServiceMock.create(desired);
83+
}
84+
85+
@Override
86+
public ExternalResource update(ExternalResource actual, ExternalResource desired,
87+
BulkDependentTestCustomResource primary, Context<BulkDependentTestCustomResource> context) {
88+
return externalServiceMock.update(desired);
89+
}
90+
91+
@Override
92+
public Matcher.Result<ExternalResource> match(ExternalResource actualResource,
93+
BulkDependentTestCustomResource primary,
94+
int index, Context<BulkDependentTestCustomResource> context) {
95+
var desired = desired(primary, index, context);
96+
return Matcher.Result.computed(desired.equals(actualResource), desired);
97+
}
98+
99+
private static String toExternalResourceId(BulkDependentTestCustomResource primary, int i) {
100+
return primary.getMetadata().getName() + EXTERNAL_RESOURCE_NAME_DELIMITER +
101+
primary.getMetadata().getNamespace() +
102+
EXTERNAL_RESOURCE_NAME_DELIMITER + i;
103+
}
104+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.javaoperatorsdk.operator.sample.bulkdependent.external;
2+
3+
import java.util.Objects;
4+
5+
public class ExternalResource {
6+
7+
private String id;
8+
private String data;
9+
10+
public ExternalResource(String id, String data) {
11+
this.id = id;
12+
this.data = data;
13+
}
14+
15+
public String getId() {
16+
return id;
17+
}
18+
19+
public String getData() {
20+
return data;
21+
}
22+
23+
@Override
24+
public boolean equals(Object o) {
25+
if (this == o)
26+
return true;
27+
if (o == null || getClass() != o.getClass())
28+
return false;
29+
ExternalResource that = (ExternalResource) o;
30+
return Objects.equals(id, that.id) && Objects.equals(data, that.data);
31+
}
32+
33+
@Override
34+
public int hashCode() {
35+
return Objects.hash(id, data);
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.javaoperatorsdk.operator.sample.bulkdependent.external;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.Optional;
7+
import java.util.concurrent.ConcurrentHashMap;
8+
9+
public class ExternalServiceMock {
10+
11+
private static ExternalServiceMock serviceMock = new ExternalServiceMock();
12+
13+
private Map<String, ExternalResource> resourceMap = new ConcurrentHashMap<>();
14+
15+
public ExternalResource create(ExternalResource externalResource) {
16+
resourceMap.put(externalResource.getId(), externalResource);
17+
return externalResource;
18+
}
19+
20+
public Optional<ExternalResource> read(String id) {
21+
return Optional.ofNullable(resourceMap.get(id));
22+
}
23+
24+
public ExternalResource update(ExternalResource externalResource) {
25+
return resourceMap.put(externalResource.getId(), externalResource);
26+
}
27+
28+
public Optional<ExternalResource> delete(String id) {
29+
return Optional.ofNullable(resourceMap.remove(id));
30+
}
31+
32+
public List<ExternalResource> listResources() {
33+
return new ArrayList<>(resourceMap.values());
34+
}
35+
36+
public static ExternalServiceMock getInstance() {
37+
return serviceMock;
38+
}
39+
}

0 commit comments

Comments
 (0)