Skip to content

Commit 34d4481

Browse files
committed
OpenAPIHolderImpl.resolveExternalRef throws java.lang.IllegalStateException
See #2844 To prevent from a recursive update of the same key in the externalSolvingRefs, avoid computeIfAbsent and continue walking the references path only when an uncompleted future has effectively been put in the map. Signed-off-by: Thomas Segismont <[email protected]>
1 parent 5ec7457 commit 34d4481

1 file changed

Lines changed: 11 additions & 9 deletions

File tree

vertx-web-openapi/src/main/java/io/vertx/ext/web/openapi/impl/OpenAPIHolderImpl.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,17 @@ private void deepSubstituteForValidation(Object obj, JsonPointer scope,
263263
}
264264

265265
private Future<JsonObject> resolveExternalRef(final URI ref) {
266-
return externalSolvingRefs.computeIfAbsent(ref,
267-
uri ->
268-
((URIUtils.isRemoteURI(uri)) ? solveRemoteRef(uri) : solveLocalRef(uri))
269-
.compose(j -> {
270-
absolutePaths.put(uri, j); // Circular refs hell!
271-
return walkAndSolve(j, uri).map(j);
272-
})
273-
274-
);
266+
Promise<JsonObject> promise = Promise.promise();
267+
Future<JsonObject> previous = externalSolvingRefs.putIfAbsent(ref, promise.future());
268+
if (previous != null) {
269+
return previous;
270+
}
271+
Future<JsonObject> solvedRef = URIUtils.isRemoteURI(ref) ? solveRemoteRef(ref) : solveLocalRef(ref);
272+
solvedRef.compose(jsonObject -> {
273+
absolutePaths.put(ref, jsonObject);
274+
return walkAndSolve(jsonObject, ref).map(jsonObject);
275+
}).onComplete(promise);
276+
return promise.future();
275277
}
276278

277279
private Future<JsonObject> solveRemoteRef(final URI ref) {

0 commit comments

Comments
 (0)