Skip to content

Commit c29ce11

Browse files
authored
feat: conversion hooks integration tests (#25)
1 parent ff8836d commit c29ce11

File tree

39 files changed

+738
-18
lines changed

39 files changed

+738
-18
lines changed

core/pom.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050

5151

5252
<dependencies>
53-
<!-- We use the OpenShift client, because functionally it is a superset of the Kubernetes client -->
5453
<dependency>
5554
<groupId>io.fabric8</groupId>
5655
<artifactId>kubernetes-client</artifactId>

core/src/main/java/io/javaoperatorsdk/webhook/conversion/AsyncConversionController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public void registerMapper(AsyncMapper<?, ?> mapper) {
2828
throw new IllegalStateException(MAPPER_ALREADY_REGISTERED_FOR_VERSION_MESSAGE + version);
2929
}
3030
mappers.put(version, mapper);
31+
Utils.registerCustomKind(
32+
Utils.getFirstTypeArgumentFromInterface(mapper.getClass(), AsyncMapper.class));
3133
}
3234

3335
@Override

core/src/main/java/io/javaoperatorsdk/webhook/conversion/ConversionController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public void registerMapper(Mapper<?, ?> mapper) {
2727
throw new IllegalStateException(MAPPER_ALREADY_REGISTERED_FOR_VERSION_MESSAGE + version);
2828
}
2929
mappers.put(version, mapper);
30+
Utils.registerCustomKind(
31+
Utils.getFirstTypeArgumentFromInterface(mapper.getClass(), Mapper.class));
3032
}
3133

3234
@Override

core/src/main/java/io/javaoperatorsdk/webhook/conversion/Utils.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package io.javaoperatorsdk.webhook.conversion;
22

3+
import java.lang.reflect.ParameterizedType;
4+
import java.util.Arrays;
5+
6+
import io.fabric8.kubernetes.api.model.HasMetadata;
7+
import io.fabric8.kubernetes.internal.KubernetesDeserializer;
8+
39
public class Utils {
410

511
private Utils() {}
@@ -12,4 +18,25 @@ public static String versionOfApiVersion(String apiVersion) {
1218
var lastDelimiter = apiVersion.lastIndexOf("/");
1319
return apiVersion.substring(lastDelimiter + 1);
1420
}
21+
22+
public static void registerCustomKind(Class<? extends HasMetadata> clazz) {
23+
KubernetesDeserializer.registerCustomKind(HasMetadata.getApiVersion(clazz),
24+
HasMetadata.getKind(clazz), clazz);
25+
}
26+
27+
@SuppressWarnings("unchecked")
28+
public static Class<? extends HasMetadata> getFirstTypeArgumentFromInterface(Class<?> clazz,
29+
Class<?> expectedImplementedInterface) {
30+
return (Class<? extends HasMetadata>) Arrays.stream(clazz.getGenericInterfaces())
31+
.filter(type -> type.getTypeName().startsWith(expectedImplementedInterface.getName())
32+
&& type instanceof ParameterizedType)
33+
.map(ParameterizedType.class::cast)
34+
.findFirst()
35+
.map(t -> (Class<?>) t.getActualTypeArguments()[0])
36+
.orElseThrow(() -> new RuntimeException(
37+
"Couldn't retrieve generic parameter type from " + clazz.getSimpleName()
38+
+ " because it doesn't implement "
39+
+ expectedImplementedInterface.getSimpleName()
40+
+ " directly"));
41+
}
1542
}

core/src/test/java/io/javaoperatorsdk/webhook/conversion/UtilsTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
import org.junit.jupiter.api.Test;
44

5+
import io.javaoperatorsdk.webhook.conversion.crd.CustomResourceV1;
6+
import io.javaoperatorsdk.webhook.conversion.crd.CustomResourceV2;
7+
import io.javaoperatorsdk.webhook.conversion.mapper.AsyncV1Mapper;
8+
import io.javaoperatorsdk.webhook.conversion.mapper.AsyncV2Mapper;
9+
import io.javaoperatorsdk.webhook.conversion.mapper.CustomResourceV1Mapper;
10+
import io.javaoperatorsdk.webhook.conversion.mapper.CustomResourceV2Mapper;
11+
512
import static org.assertj.core.api.Assertions.assertThat;
613
import static org.junit.jupiter.api.Assertions.*;
714

@@ -13,4 +20,16 @@ void getsVersionFromApiVersion() {
1320
assertThat(Utils.versionOfApiVersion("extensions/v1beta1")).isEqualTo("v1beta1");
1421
}
1522

23+
@Test
24+
void getMapperResourceType() {
25+
assertThat(Utils.getFirstTypeArgumentFromInterface(CustomResourceV1Mapper.class, Mapper.class))
26+
.isEqualTo(CustomResourceV1.class);
27+
assertThat(Utils.getFirstTypeArgumentFromInterface(CustomResourceV2Mapper.class, Mapper.class))
28+
.isEqualTo(CustomResourceV2.class);
29+
assertThat(Utils.getFirstTypeArgumentFromInterface(AsyncV1Mapper.class, AsyncMapper.class))
30+
.isEqualTo(CustomResourceV1.class);
31+
assertThat(Utils.getFirstTypeArgumentFromInterface(AsyncV2Mapper.class, AsyncMapper.class))
32+
.isEqualTo(CustomResourceV2.class);
33+
}
34+
1635
}

core/src/test/java/io/javaoperatorsdk/webhook/conversion/crd/CustomResourceV1.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
@Group("sample.javaoperatorsdk")
1111
@Version("v1")
12-
@Kind("MultiVersionCustomResource")
12+
@Kind("MultiVersionTestCustomResource")
1313
@ShortNames("mv1")
1414
public class CustomResourceV1
1515
extends

core/src/test/java/io/javaoperatorsdk/webhook/conversion/crd/CustomResourceV2.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
@Group("sample.javaoperatorsdk")
1111
@Version(value = "v2", storage = false)
12-
@Kind("MultiVersionCustomResource")
12+
@Kind("MultiVersionTestCustomResource")
1313
@ShortNames("mv2")
1414
public class CustomResourceV2
1515
extends

core/src/test/java/io/javaoperatorsdk/webhook/conversion/crd/CustomResourceV3.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
@Group("sample.javaoperatorsdk")
1111
@Version(value = "v3", storage = false)
12-
@Kind("MultiVersionCustomResource")
12+
@Kind("MultiVersionTestCustomResource")
1313
@ShortNames("mv3")
1414
public class CustomResourceV3
1515
extends

pom.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,6 @@
158158
<groupId>org.apache.maven.plugins</groupId>
159159
<artifactId>maven-surefire-plugin</artifactId>
160160
<version>${maven-surefire-plugin.version}</version>
161-
<configuration>
162-
<rerunFailingTestsCount>3</rerunFailingTestsCount>
163-
</configuration>
164161
</plugin>
165162
<plugin>
166163
<groupId>org.apache.maven.plugins</groupId>

samples/commons/pom.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>io.javaoperatorsdk</groupId>
7+
<artifactId>admission-controller-framework-samples</artifactId>
8+
<version>0.2.1-SNAPSHOT</version>
9+
</parent>
10+
11+
<groupId>io.javaoperatorsdk.admissioncontroller.sample</groupId>
12+
<artifactId>sample-commons</artifactId>
13+
<name>Admission Controller Framework - Samples - Commons</name>
14+
15+
<properties>
16+
<java.version>11</java.version>
17+
<spring-boot-dependencies.version>2.6.6</spring-boot-dependencies.version>
18+
</properties>
19+
20+
<dependencies>
21+
<dependency>
22+
<groupId>io.fabric8</groupId>
23+
<artifactId>kubernetes-client</artifactId>
24+
</dependency>
25+
<dependency>
26+
<groupId>io.javaoperatorsdk</groupId>
27+
<artifactId>admission-controller-framework-core</artifactId>
28+
<version>${project.version}</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>io.fabric8</groupId>
32+
<artifactId>crd-generator-apt</artifactId>
33+
</dependency>
34+
</dependencies>
35+
36+
<build>
37+
<plugins>
38+
<plugin>
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-maven-plugin</artifactId>
41+
<version>${spring-boot-dependencies.version}</version>
42+
</plugin>
43+
</plugins>
44+
</build>
45+
46+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.customresource;
2+
3+
import io.fabric8.kubernetes.client.CustomResource;
4+
import io.fabric8.kubernetes.model.annotation.Group;
5+
import io.fabric8.kubernetes.model.annotation.Kind;
6+
import io.fabric8.kubernetes.model.annotation.ShortNames;
7+
import io.fabric8.kubernetes.model.annotation.Version;
8+
9+
@Group("sample.javaoperatorsdk")
10+
@Version(value = "v1", storage = false)
11+
@Kind("MultiVersionCustomResource")
12+
@ShortNames("tcr")
13+
public class MultiVersionCustomResource
14+
extends CustomResource<MultiVersionCustomResourceSpec, MultiVersionCustomResourceStatus> {
15+
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.customresource;
2+
3+
public class MultiVersionCustomResourceSpec {
4+
5+
private int value;
6+
7+
public int getValue() {
8+
return value;
9+
}
10+
11+
public MultiVersionCustomResourceSpec setValue(int value) {
12+
this.value = value;
13+
return this;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.customresource;
2+
3+
public class MultiVersionCustomResourceSpecV2 {
4+
5+
private String value;
6+
7+
private String additionalValue;
8+
9+
public String getValue() {
10+
return value;
11+
}
12+
13+
public MultiVersionCustomResourceSpecV2 setValue(String value) {
14+
this.value = value;
15+
return this;
16+
}
17+
18+
public String getAdditionalValue() {
19+
return additionalValue;
20+
}
21+
22+
public void setAdditionalValue(String additionalValue) {
23+
this.additionalValue = additionalValue;
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.customresource;
2+
3+
public class MultiVersionCustomResourceStatus {
4+
5+
private Boolean ready;
6+
7+
public Boolean getReady() {
8+
return ready;
9+
}
10+
11+
public MultiVersionCustomResourceStatus setReady(Boolean ready) {
12+
this.ready = ready;
13+
return this;
14+
}
15+
}
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.customresource;
2+
3+
4+
public class MultiVersionCustomResourceStatusV2 {
5+
6+
private Boolean ready;
7+
8+
private String message;
9+
10+
public Boolean getReady() {
11+
return ready;
12+
}
13+
14+
public MultiVersionCustomResourceStatusV2 setReady(Boolean ready) {
15+
this.ready = ready;
16+
return this;
17+
}
18+
19+
public String getMessage() {
20+
return message;
21+
}
22+
23+
public MultiVersionCustomResourceStatusV2 setMessage(String message) {
24+
this.message = message;
25+
return this;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.customresource;
2+
3+
import io.fabric8.kubernetes.client.CustomResource;
4+
import io.fabric8.kubernetes.model.annotation.Group;
5+
import io.fabric8.kubernetes.model.annotation.Kind;
6+
import io.fabric8.kubernetes.model.annotation.ShortNames;
7+
import io.fabric8.kubernetes.model.annotation.Version;
8+
9+
@Group("sample.javaoperatorsdk")
10+
@Version(value = "v2")
11+
@Kind("MultiVersionCustomResource")
12+
@ShortNames("tcr")
13+
public class MultiVersionCustomResourceV2
14+
extends CustomResource<MultiVersionCustomResourceSpecV2, MultiVersionCustomResourceStatusV2> {
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.mapper;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
import java.util.concurrent.CompletionStage;
5+
6+
import io.javaoperatorsdk.webhook.conversion.AsyncMapper;
7+
import io.javaoperatorsdk.webhook.conversion.TargetVersion;
8+
import io.javaoperatorsdk.webhook.sample.commons.customresource.MultiVersionCustomResource;
9+
import io.javaoperatorsdk.webhook.sample.commons.customresource.MultiVersionCustomResourceV2;
10+
11+
@TargetVersion("v1")
12+
public class AsyncV1Mapper
13+
implements AsyncMapper<MultiVersionCustomResource, MultiVersionCustomResourceV2> {
14+
15+
private V1Mapper mapper = new V1Mapper();
16+
17+
@Override
18+
public CompletionStage<MultiVersionCustomResourceV2> toHub(MultiVersionCustomResource resource) {
19+
return CompletableFuture.completedStage(mapper.toHub(resource));
20+
}
21+
22+
@Override
23+
public CompletionStage<MultiVersionCustomResource> fromHub(
24+
MultiVersionCustomResourceV2 testCustomResourceV2) {
25+
return CompletableFuture.completedStage(mapper.fromHub(testCustomResourceV2));
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.javaoperatorsdk.webhook.sample.commons.mapper;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
import java.util.concurrent.CompletionStage;
5+
6+
import io.javaoperatorsdk.webhook.conversion.AsyncMapper;
7+
import io.javaoperatorsdk.webhook.conversion.TargetVersion;
8+
import io.javaoperatorsdk.webhook.sample.commons.customresource.MultiVersionCustomResourceV2;
9+
10+
@TargetVersion("v2")
11+
public class AsyncV2Mapper
12+
implements AsyncMapper<MultiVersionCustomResourceV2, MultiVersionCustomResourceV2> {
13+
14+
private V2Mapper mapper = new V2Mapper();
15+
16+
@Override
17+
public CompletionStage<MultiVersionCustomResourceV2> toHub(
18+
MultiVersionCustomResourceV2 resource) {
19+
return CompletableFuture.completedStage(mapper.toHub(resource));
20+
}
21+
22+
@Override
23+
public CompletionStage<MultiVersionCustomResourceV2> fromHub(
24+
MultiVersionCustomResourceV2 multiVersionCustomResourceV2) {
25+
return CompletableFuture.completedStage(mapper.fromHub(multiVersionCustomResourceV2));
26+
}
27+
}

0 commit comments

Comments
 (0)