Skip to content

Commit d5c1483

Browse files
committed
Add custom Constructor to Yaml to fix issue kubernetes-client#241
1 parent c7087e4 commit d5c1483

File tree

2 files changed

+69
-21
lines changed

2 files changed

+69
-21
lines changed

util/src/main/java/io/kubernetes/client/util/Yaml.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@
2121
import java.util.HashMap;
2222
import java.util.Map;
2323
import java.util.Set;
24+
25+
import io.kubernetes.client.custom.IntOrString;
2426
import org.slf4j.Logger;
2527
import org.slf4j.LoggerFactory;
28+
import org.yaml.snakeyaml.constructor.Constructor;
29+
import org.yaml.snakeyaml.nodes.Node;
30+
import org.yaml.snakeyaml.nodes.ScalarNode;
2631

2732
public class Yaml {
28-
private static org.yaml.snakeyaml.Yaml yaml = new org.yaml.snakeyaml.Yaml();
33+
private static org.yaml.snakeyaml.Yaml yaml = new org.yaml.snakeyaml.Yaml(new CustomConstructor());
2934
private static Map<String, Class<?>> classes = new HashMap<>();
3035

3136
static final Logger logger = LoggerFactory.getLogger(Yaml.class);
@@ -185,4 +190,26 @@ public static <T> T loadAs(File f, Class<T> clazz) throws IOException {
185190
public static <T> T loadAs(Reader reader, Class<T> clazz) {
186191
return yaml.loadAs(reader, clazz);
187192
}
193+
194+
195+
/**
196+
* Defines constructor logic for custom types in this library.
197+
*/
198+
public static class CustomConstructor extends Constructor {
199+
@Override
200+
protected Object constructObject(Node node) {
201+
if(node.getType() == IntOrString.class) {
202+
return constructIntOrString((ScalarNode)node);
203+
}
204+
return super.constructObject(node);
205+
}
206+
207+
private IntOrString constructIntOrString(ScalarNode node) {
208+
try {
209+
return new IntOrString(Integer.parseInt(node.getValue()));
210+
} catch (NumberFormatException err) {
211+
return new IntOrString(node.getValue());
212+
}
213+
}
214+
}
188215
}

util/src/test/java/io/kubernetes/client/util/YamlTest.java

+41-20
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,44 @@
1212
*/
1313
package io.kubernetes.client.util;
1414

15-
import static org.junit.Assert.*;
16-
15+
import io.kubernetes.client.custom.IntOrString;
1716
import io.kubernetes.client.models.V1ObjectMeta;
17+
import io.kubernetes.client.models.V1Service;
18+
import io.kubernetes.client.models.V1ServicePort;
19+
import org.junit.Test;
20+
1821
import java.io.StringReader;
1922
import java.lang.reflect.Method;
20-
import org.junit.Test;
23+
24+
import static org.junit.Assert.*;
2125

2226
public class YamlTest {
2327
@Test
2428
public void testLoad() {
25-
String[] kinds = new String[] {"Pod", "Deployment", "ClusterRole", "APIService", "Scale"};
29+
String[] kinds = new String[]{"Pod", "Deployment", "ClusterRole", "APIService", "Scale"};
2630
String[] apiVersions =
27-
new String[] {"v1", "v1beta2", "v1alpha1", "v1beta1", "extensions/v1beta1"};
31+
new String[]{"v1", "v1beta2", "v1alpha1", "v1beta1", "extensions/v1beta1"};
2832
String[] classNames =
29-
new String[] {
30-
"V1Pod",
31-
"V1beta2Deployment",
32-
"V1alpha1ClusterRole",
33-
"V1beta1APIService",
34-
"ExtensionsV1beta1Scale"
35-
};
33+
new String[]{
34+
"V1Pod",
35+
"V1beta2Deployment",
36+
"V1alpha1ClusterRole",
37+
"V1beta1APIService",
38+
"ExtensionsV1beta1Scale"
39+
};
3640
for (int i = 0; i < kinds.length; i++) {
3741
String kind = kinds[i];
3842
String className = classNames[i];
3943
try {
4044
String input =
41-
"kind: "
42-
+ kind
43-
+ "\n"
44-
+ "apiVersion: "
45-
+ apiVersions[i]
46-
+ "\n"
47-
+ "metadata:\n"
48-
+ " name: foo";
45+
"kind: "
46+
+ kind
47+
+ "\n"
48+
+ "apiVersion: "
49+
+ apiVersions[i]
50+
+ "\n"
51+
+ "metadata:\n"
52+
+ " name: foo";
4953
Object obj = Yaml.load(new StringReader(input));
5054
Method m = obj.getClass().getMethod("getMetadata");
5155
V1ObjectMeta metadata = (V1ObjectMeta) m.invoke(obj);
@@ -57,4 +61,21 @@ public void testLoad() {
5761
}
5862
}
5963
}
64+
65+
@Test
66+
public void testLoadIntOrString() {
67+
try {
68+
String strInput = "targetPort: test";
69+
String intInput = "targetPort: 1";
70+
71+
V1ServicePort stringPort = Yaml.loadAs(strInput, V1ServicePort.class);
72+
V1ServicePort intPort = Yaml.loadAs(intInput, V1ServicePort.class);
73+
74+
assertFalse("Target port for 'stringPort' was parsed to an integer, string expected.", stringPort.getTargetPort().isInteger());
75+
assertTrue("Target port for 'intPort' was parsed to a string, integer expected.", intPort.getTargetPort().isInteger());
76+
77+
} catch (Exception ex) {
78+
assertNull("Unexpected exception: " + ex.toString(), ex);
79+
}
80+
}
6081
}

0 commit comments

Comments
 (0)