Skip to content

Commit a16649f

Browse files
authored
fix: JsonUnwrappedDeserializer works when serialized data is not provided
Signed-off-by: Marc Nuri <[email protected]>
1 parent c1c4b0a commit a16649f

File tree

2 files changed

+43
-68
lines changed

2 files changed

+43
-68
lines changed

Diff for: kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/JsonUnwrappedDeserializer.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,11 @@ public T deserialize(JsonParser jsonParser, DeserializationContext deserializati
162162

163163
boolean replaced = false;
164164
for (UnwrappedInfo unwrapped : unwrappedInfos) {
165-
final ObjectNode unwrappedNode = unwrappedNodes.computeIfAbsent(unwrapped,
166-
k -> deserializationContext.getNodeFactory().objectNode());
167165
final String transformed = unwrapped.nameTransformer.reverse(key);
166+
final ObjectNode unwrappedNode = unwrappedNodes.getOrDefault(unwrapped,
167+
deserializationContext.getNodeFactory().objectNode());
168168
if (transformed != null && !ownPropertyNames.contains(key) && unwrapped.beanPropertyNames.contains(transformed)) {
169+
unwrappedNodes.putIfAbsent(unwrapped, unwrappedNode);
169170
unwrappedNode.replace(transformed, value);
170171
replaced = true;
171172
}

Diff for: kubernetes-model-generator/kubernetes-model-common/src/test/java/io/fabric8/kubernetes/model/jackson/JsonUnwrappedDeserializerTest.java

+40-66
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2424
import lombok.Data;
2525
import lombok.NoArgsConstructor;
26+
import org.assertj.core.api.InstanceOfAssertFactories;
2627
import org.junit.jupiter.api.BeforeEach;
2728
import org.junit.jupiter.api.DisplayName;
2829
import org.junit.jupiter.api.Nested;
@@ -31,16 +32,9 @@
3132
import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.DEDUCTION;
3233
import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NONE;
3334
import static org.assertj.core.api.Assertions.assertThat;
34-
import static org.junit.jupiter.api.Assertions.assertEquals;
35-
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
36-
import static org.junit.jupiter.api.Assertions.assertNotNull;
3735

3836
class JsonUnwrappedDeserializerTest {
3937

40-
private static final String EXPECTED_VALUE_A = "Value A";
41-
private static final String EXPECTED_VALUE_B = "Value B";
42-
private static final String EXPECTED_VALUE_C = "Value C";
43-
4438
private ObjectMapper mapper;
4539

4640
@BeforeEach
@@ -53,22 +47,39 @@ class Deserialize {
5347

5448
@Test
5549
@DisplayName("Single @JsonUnwrapped polymorphic type")
56-
void singleInterfaceWithJsonWrapped() throws JsonProcessingException {
57-
RootClass instance = mapper.readValue("{ \"stringField\": \"" + EXPECTED_VALUE_A + "\", "
58-
+ "\"extendedField\": \"" + EXPECTED_VALUE_B + "\", "
59-
+ "\"nestedField\": \"" + EXPECTED_VALUE_C + "\" }", RootClass.class);
60-
// Verify normal fields works along to the json-wrapped fields
61-
assertEquals(EXPECTED_VALUE_A, instance.stringField);
62-
63-
// Verify interfaces are supported at root level
64-
assertNotNull(instance.rootInterface, "Interface was not deserialized!");
65-
assertInstanceOf(RootImplementation.class, instance.rootInterface);
66-
RootImplementation rootImplementation = ((RootImplementation) instance.rootInterface);
67-
assertEquals(EXPECTED_VALUE_B, rootImplementation.extendedField);
68-
69-
// Verify nested interfaces are also supported
70-
assertInstanceOf(NestedImplementation.class, rootImplementation.nestedInterface);
71-
assertEquals(EXPECTED_VALUE_C, ((NestedImplementation) rootImplementation.nestedInterface).nestedField);
50+
void singleJsonWrappedPolymorphicField() throws JsonProcessingException {
51+
final RootClass result = mapper.readValue("{" +
52+
"\"stringField\": \"string-field-value\", " +
53+
"\"extendedField\": \"extended-field-value\", " +
54+
"\"nestedField\": \"nested-field-value\"" +
55+
"}", RootClass.class);
56+
assertThat(result)
57+
// Verify normal fields works along to the json-wrapped fields
58+
.hasFieldOrPropertyWithValue("stringField", "string-field-value")
59+
// Verify interfaces are supported at root level
60+
.extracting(RootClass::getRootInterface)
61+
.isNotNull()
62+
.asInstanceOf(InstanceOfAssertFactories.type(RootImplementation.class))
63+
.hasFieldOrPropertyWithValue("extendedField", "extended-field-value")
64+
// Verify nested interfaces are also supported
65+
.extracting(RootImplementation::getNestedInterface)
66+
.isNotNull()
67+
.asInstanceOf(InstanceOfAssertFactories.type(NestedImplementation.class))
68+
.hasFieldOrPropertyWithValue("nestedField", "nested-field-value");
69+
}
70+
71+
@Test
72+
@DisplayName("Single @JsonUnwrapped polymorphic field with missing data")
73+
void singleJsonWrappedPolymorphicFieldWithMissingDataForUnwrapped() throws JsonProcessingException {
74+
final RootClass result = mapper.readValue("{" +
75+
"\"stringField\": \"string-field-value\"" +
76+
"}", RootClass.class);
77+
assertThat(result)
78+
// Verify normal fields works along to the json-wrapped fields
79+
.hasFieldOrPropertyWithValue("stringField", "string-field-value")
80+
// Verify interfaces are supported at root level
81+
.extracting(RootClass::getRootInterface)
82+
.isNull();
7283
}
7384

7485
@Test
@@ -167,6 +178,8 @@ public static class BarImpl implements Bar {
167178
private String bar;
168179
}
169180

181+
@Data
182+
@NoArgsConstructor
170183
@JsonDeserialize(using = io.fabric8.kubernetes.model.jackson.JsonUnwrappedDeserializer.class)
171184
public static class RootClass {
172185

@@ -175,25 +188,6 @@ public static class RootClass {
175188
@JsonUnwrapped
176189
private RootInterface rootInterface;
177190

178-
public RootClass() {
179-
180-
}
181-
182-
public String getStringField() {
183-
return stringField;
184-
}
185-
186-
public void setStringField(String stringField) {
187-
this.stringField = stringField;
188-
}
189-
190-
public RootInterface getRootInterface() {
191-
return rootInterface;
192-
}
193-
194-
public void setRootInterface(RootInterface rootInterface) {
195-
this.rootInterface = rootInterface;
196-
}
197191
}
198192

199193
@JsonSubTypes(@JsonSubTypes.Type(RootImplementation.class))
@@ -202,24 +196,14 @@ interface RootInterface {
202196

203197
}
204198

199+
@Data
200+
@NoArgsConstructor
205201
@JsonDeserialize(using = io.fabric8.kubernetes.model.jackson.JsonUnwrappedDeserializer.class)
206202
public static class RootImplementation implements RootInterface {
207203

208204
private String extendedField;
209205
@JsonUnwrapped
210206
private NestedInterface nestedInterface;
211-
212-
public RootImplementation() {
213-
214-
}
215-
216-
public String getExtendedField() {
217-
return extendedField;
218-
}
219-
220-
public void setExtendedField(String extendedField) {
221-
this.extendedField = extendedField;
222-
}
223207
}
224208

225209
@JsonSubTypes(@JsonSubTypes.Type(NestedImplementation.class))
@@ -228,19 +212,9 @@ interface NestedInterface {
228212

229213
}
230214

215+
@Data
216+
@NoArgsConstructor
231217
public static class NestedImplementation implements NestedInterface {
232218
private String nestedField;
233-
234-
public NestedImplementation() {
235-
236-
}
237-
238-
public String getNestedField() {
239-
return nestedField;
240-
}
241-
242-
public void setNestedField(String nestedField) {
243-
this.nestedField = nestedField;
244-
}
245219
}
246220
}

0 commit comments

Comments
 (0)