Skip to content

Commit b79b25c

Browse files
fix(docker): resolve the issue of Unrecognized field "child" (#6359) (#6360)
* test(docker): add a test to demonstrate the issue of `Failed to parse ResponseBody : Unrecognized field "child"` * fix(docker): resolve the issue of `Failed to parse ResponseBody : Unrecognized field "child"` when google cloud artifact registry responds with additional fields upon invoking tags list api (cherry picked from commit 7c4514a) Co-authored-by: Kiran Godishala <53332225+kirangodishala@users.noreply.github.com>
1 parent dd4791f commit b79b25c

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

clouddriver-docker/src/main/groovy/com/netflix/spinnaker/clouddriver/docker/registry/api/v2/client/DockerRegistryClient.groovy

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.netflix.spinnaker.clouddriver.docker.registry.api.v2.client
1818

19+
import com.fasterxml.jackson.databind.DeserializationFeature
1920
import com.fasterxml.jackson.databind.ObjectMapper
2021
import com.google.gson.Gson
2122
import com.netflix.spinnaker.clouddriver.docker.registry.api.v2.DockerUserAgent
@@ -163,6 +164,15 @@ class DockerRegistryClient {
163164

164165
final static String userAgent = DockerUserAgent.getUserAgent()
165166
final int paginateSize
167+
static ObjectMapper objectMapper
168+
169+
private static ObjectMapper getObjectMapper() {
170+
if (objectMapper == null) {
171+
objectMapper = new ObjectMapper()
172+
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
173+
}
174+
return objectMapper
175+
}
166176

167177
String getBasicAuth() {
168178
return tokenService?.basicAuth
@@ -317,9 +327,8 @@ class DockerRegistryClient {
317327
throw new DockerRegistryOperationException("ResponseBody cannot be null")
318328
}
319329
try {
320-
def objectMapper = new ObjectMapper()
321330
def jsonString = responseBody.string()
322-
return objectMapper.readValue(jsonString, aClass)
331+
return getObjectMapper().readValue(jsonString, aClass)
323332
} catch (Exception e) {
324333
throw new DockerRegistryOperationException("Failed to parse ResponseBody : ${e.message}", e)
325334
}

clouddriver-docker/src/test/java/com/netflix/spinnaker/clouddriver/docker/registry/api/v2/client/DockerRegistryClientTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,4 +217,35 @@ public void getTagsWithNextLinkEncryptedAndEncoded() {
217217
urlMatching(
218218
tagsListEndPointMinusQueryParams + "\\?last=" + expectedEncodedParam + "&n=5")));
219219
}
220+
221+
@Test
222+
public void testTagsResponse_With_AdditionalFields() throws JsonProcessingException {
223+
Map<String, Object> tagsResponse =
224+
Map.of(
225+
"child",
226+
new String[] {},
227+
"manifest",
228+
Map.of(
229+
"sha256:ec1b05dxxxxxxxxxxxxxxxxxxxedb1d6a4",
230+
Map.of(
231+
"mediaType",
232+
"application/vnd.docker.distribution.manifest.v2+json",
233+
"tag",
234+
new String[] {"1.0.0", "2.0.1"})),
235+
"name",
236+
"library/nginx",
237+
"tags",
238+
new String[] {"1", "1-alpine", "1-alpine-otel", "1-alpine-perl", "1-alpine-slim"});
239+
240+
wmDockerRegistry.stubFor(
241+
WireMock.get(urlMatching("/v2/library/nginx/tags/list\\?n=5"))
242+
.willReturn(
243+
aResponse()
244+
.withStatus(HttpStatus.OK.value())
245+
.withBody(objectMapper.writeValueAsString(tagsResponse))));
246+
247+
DockerRegistryTags dockerRegistryTags = dockerRegistryClient.getTags("library/nginx");
248+
String[] tags = (String[]) tagsResponse.get("tags");
249+
assertIterableEquals(Arrays.asList(tags), dockerRegistryTags.getTags());
250+
}
220251
}

0 commit comments

Comments
 (0)