Skip to content

Commit 4884d1b

Browse files
authored
Merge pull request kubernetes-client#1692 from yue9944882/cherry-pick-11-yaml-construct
Cherry-pick 11: Update the CustomConstructor class for SnakeYAML
2 parents 6706db7 + a1cfe10 commit 4884d1b

4 files changed

Lines changed: 85 additions & 12 deletions

File tree

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

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.slf4j.LoggerFactory;
3636
import org.yaml.snakeyaml.DumperOptions;
3737
import org.yaml.snakeyaml.constructor.Constructor;
38+
import org.yaml.snakeyaml.constructor.SafeConstructor;
3839
import org.yaml.snakeyaml.introspector.Property;
3940
import org.yaml.snakeyaml.nodes.MappingNode;
4041
import org.yaml.snakeyaml.nodes.Node;
@@ -79,7 +80,7 @@ public static Object load(File f) throws IOException {
7980
* @throws IOException If an error occurs while reading the YAML.
8081
*/
8182
public static Object load(Reader reader) throws IOException {
82-
Map<String, Object> data = getSnakeYaml().load(reader);
83+
Map<String, Object> data = getSnakeYaml(null).load(reader);
8384
return modelMapper(data);
8485
}
8586

@@ -93,7 +94,7 @@ public static Object load(Reader reader) throws IOException {
9394
* @throws IOException If an error occurs while reading the YAML.
9495
*/
9596
public static <T> T loadAs(String content, Class<T> clazz) {
96-
return getSnakeYaml().loadAs(new StringReader(content), clazz);
97+
return getSnakeYaml(clazz).loadAs(new StringReader(content), clazz);
9798
}
9899

99100
/**
@@ -105,7 +106,7 @@ public static <T> T loadAs(String content, Class<T> clazz) {
105106
* @throws IOException If an error occurs while reading the YAML.
106107
*/
107108
public static <T> T loadAs(File f, Class<T> clazz) throws IOException {
108-
return getSnakeYaml().loadAs(new FileReader(f), clazz);
109+
return getSnakeYaml(clazz).loadAs(new FileReader(f), clazz);
109110
}
110111

111112
/**
@@ -118,7 +119,7 @@ public static <T> T loadAs(File f, Class<T> clazz) throws IOException {
118119
* @throws IOException If an error occurs while reading the YAML.
119120
*/
120121
public static <T> T loadAs(Reader reader, Class<T> clazz) {
121-
return getSnakeYaml().loadAs(reader, clazz);
122+
return getSnakeYaml(clazz).loadAs(reader, clazz);
122123
}
123124

124125
/**
@@ -161,7 +162,7 @@ public static List<Object> loadAll(File f) throws IOException {
161162
* @throws IOException If an error occurs while reading the YAML.
162163
*/
163164
public static List<Object> loadAll(Reader reader) throws IOException {
164-
Iterable<Object> iterable = getSnakeYaml().loadAll(reader);
165+
Iterable<Object> iterable = getSnakeYaml(null).loadAll(reader);
165166
List<Object> list = new ArrayList<Object>();
166167
for (Object object : iterable) {
167168
if (object != null) {
@@ -183,7 +184,7 @@ public static List<Object> loadAll(Reader reader) throws IOException {
183184
* @return A YAML String representing the API object.
184185
*/
185186
public static String dump(Object object) {
186-
return getSnakeYaml().dump(object);
187+
return getSnakeYaml(object.getClass()).dump(object);
187188
}
188189

189190
/**
@@ -193,7 +194,7 @@ public static String dump(Object object) {
193194
* @param writer The writer to write the YAML to.
194195
*/
195196
public static void dump(Object object, Writer writer) {
196-
getSnakeYaml().dump(object, writer);
197+
getSnakeYaml(object.getClass()).dump(object, writer);
197198
}
198199

199200
/**
@@ -203,7 +204,7 @@ public static void dump(Object object, Writer writer) {
203204
* @return A String representing the list of YAML API objects.
204205
*/
205206
public static String dumpAll(Iterator<? extends KubernetesType> data) {
206-
return getSnakeYaml().dumpAll(data);
207+
return getSnakeYaml(null).dumpAll(data);
207208
}
208209

209210
/**
@@ -213,11 +214,15 @@ public static String dumpAll(Iterator<? extends KubernetesType> data) {
213214
* @param output The writer to output the YAML String to.
214215
*/
215216
public static void dumpAll(Iterator<? extends KubernetesType> data, Writer output) {
216-
getSnakeYaml().dumpAll(data, output);
217+
getSnakeYaml(null).dumpAll(data, output);
217218
}
218219

219220
/** Defines constructor logic for custom types in this library. */
220221
public static class CustomConstructor extends Constructor {
222+
public CustomConstructor(Class<?> type) {
223+
super(type);
224+
}
225+
221226
@Override
222227
protected Object constructObject(Node node) {
223228
if (node.getType() == IntOrString.class) {
@@ -230,7 +235,6 @@ protected Object constructObject(Node node) {
230235
if (node.getType() == org.joda.time.DateTime.class) {
231236
return constructDateTime((ScalarNode) node);
232237
}
233-
234238
return super.constructObject(node);
235239
}
236240

@@ -358,8 +362,16 @@ protected NodeTuple representJavaBeanProperty(
358362
}
359363

360364
/** @return An instantiated SnakeYaml Object. */
365+
@Deprecated
361366
public static org.yaml.snakeyaml.Yaml getSnakeYaml() {
362-
return new org.yaml.snakeyaml.Yaml(new CustomConstructor(), new CustomRepresenter());
367+
return getSnakeYaml(null);
368+
}
369+
370+
private static org.yaml.snakeyaml.Yaml getSnakeYaml(Class<?> type) {
371+
if (type != null) {
372+
return new org.yaml.snakeyaml.Yaml(new CustomConstructor(type), new CustomRepresenter());
373+
}
374+
return new org.yaml.snakeyaml.Yaml(new SafeConstructor(), new CustomRepresenter());
363375
}
364376

365377
/**
@@ -382,7 +394,7 @@ private static Object modelMapper(Map<String, Object> data) throws IOException {
382394
throw new IOException(
383395
"Unknown apiVersionKind " + apiVersion + "/" + kind + " is it registered?");
384396
}
385-
return loadAs(new StringReader(getSnakeYaml().dump(data)), clazz);
397+
return loadAs(new StringReader(getSnakeYaml(clazz).dump(data)), clazz);
386398
}
387399

388400
@Deprecated
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.kubernetes.client.util;
14+
15+
public class TestPoJ {
16+
private static boolean marker = false;
17+
18+
public TestPoJ() {
19+
marker = true;
20+
}
21+
22+
public static boolean hasBeenConstructed() {
23+
return marker;
24+
}
25+
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public class YamlTest {
4747

4848
private static final URL CREATED_TIMESTAMP_FILE = Resources.getResource("test-pod.yaml");
4949

50+
private static final URL TAGGED_FILE = Resources.getResource("pod-tag.yaml");
51+
5052
private static final String[] kinds =
5153
new String[] {
5254
"Pod",
@@ -256,4 +258,26 @@ public void testDateTimeRoundTrip() {
256258
assertNull("Unexpected exception: " + ex.toString(), ex);
257259
}
258260
}
261+
262+
@Test
263+
public void testYamlCantConstructObjects() {
264+
try {
265+
String data = Resources.toString(TAGGED_FILE, UTF_8);
266+
Object pod = Yaml.load(data);
267+
} catch (Exception ex) {
268+
// pass
269+
}
270+
assertFalse("Object should not be constructed!", TestPoJ.hasBeenConstructed());
271+
}
272+
273+
@Test
274+
public void testLoadAsYamlCantConstructObjects() {
275+
try {
276+
String data = Resources.toString(TAGGED_FILE, UTF_8);
277+
V1Pod pod = Yaml.loadAs(data, V1Pod.class);
278+
} catch (Exception ex) {
279+
// pass
280+
}
281+
assertFalse("Object should not be constructed!", TestPoJ.hasBeenConstructed());
282+
}
259283
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
!!io.kubernetes.client.util.TestPoJ
2+
apiVersion: v1
3+
kind: Pod
4+
metadata:
5+
creationTimestamp: "2018-12-23T01:09:18Z"
6+
generateName: test-776d6c86cc-
7+
labels:
8+
app: test
9+
app-version: "19911"
10+
pod-template-hash: "3328274277"
11+
name: test-776d6c86cc-4zwj5
12+
namespace: default

0 commit comments

Comments
 (0)