Skip to content

Commit 13ce51d

Browse files
authored
Merge pull request #1178 from scottr-ad/master
Issue #1177 - ExternalRefProcessor - load $ref headers within external responses.
2 parents 737e881 + a0a2fd0 commit 13ce51d

File tree

6 files changed

+213
-21
lines changed

6 files changed

+213
-21
lines changed

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java

Lines changed: 115 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -256,30 +256,17 @@ public String processRefToExternalResponse(String $ref, RefFormat refFormat) {
256256
cache.putRenamedRef($ref, newRef);
257257

258258
if(response != null) {
259-
260-
String file = $ref.split("#/")[0];
261-
262-
Schema schema = null;
263259
if(response.getContent() != null){
264-
Map<String, MediaType> content = response.getContent();
265-
for( String mediaName : content.keySet()) {
266-
MediaType mediaType = content.get(mediaName);
267-
if(mediaType.getSchema()!= null) {
268-
schema = mediaType.getSchema();
269-
if (schema.get$ref() != null) {
270-
RefFormat ref = computeRefFormat(schema.get$ref());
271-
if (isAnExternalRefFormat(ref)) {
272-
processRefSchema(schema, $ref);
273-
} else {
274-
processRefToExternalSchema(file + schema.get$ref(), RefFormat.RELATIVE);
275-
}
276-
}else{
277-
processSchema(schema,file);
278-
}
279-
}
280-
}
260+
processRefContent(response.getContent(), $ref);
261+
}
262+
if(response.getHeaders() != null){
263+
processRefHeaders(response.getHeaders(), $ref);
264+
}
265+
if(response.getLinks() != null){
266+
processRefLinks(response.getLinks(), $ref);
281267
}
282268
}
269+
283270
return newRef;
284271
}
285272

@@ -396,6 +383,15 @@ public String processRefToExternalHeader(String $ref, RefFormat refFormat) {
396383
}
397384
}
398385

386+
if(header != null) {
387+
if(header.getContent() != null){
388+
processRefContent(header.getContent(), $ref);
389+
}
390+
if(header.getSchema() != null){
391+
processRefSchemaObject(header.getSchema(), $ref);
392+
}
393+
}
394+
399395
return newRef;
400396
}
401397

@@ -628,6 +624,15 @@ public String processRefToExternalParameter(String $ref, RefFormat refFormat) {
628624
}
629625
}
630626

627+
if(parameter != null) {
628+
if(parameter.getContent() != null){
629+
processRefContent(parameter.getContent(), $ref);
630+
}
631+
if(parameter.getSchema() != null){
632+
processRefSchemaObject(parameter.getSchema(), $ref);
633+
}
634+
}
635+
631636
return newRef;
632637
}
633638

@@ -691,6 +696,56 @@ public String processRefToExternalCallback(String $ref, RefFormat refFormat) {
691696
return newRef;
692697
}
693698

699+
private void processRefContent(Map<String, MediaType> content, String $ref) {
700+
for(MediaType mediaType : content.values()) {
701+
if(mediaType.getSchema() != null) {
702+
processRefSchemaObject(mediaType.getSchema(), $ref);
703+
}
704+
}
705+
}
706+
707+
private void processRefSchemaObject(Schema schema, String $ref) {
708+
String file = $ref.split("#/")[0];
709+
if (schema.get$ref() != null) {
710+
RefFormat ref = computeRefFormat(schema.get$ref());
711+
if (isAnExternalRefFormat(ref)) {
712+
processRefSchema(schema, $ref);
713+
} else {
714+
processRefToExternalSchema(file + schema.get$ref(), RefFormat.RELATIVE);
715+
}
716+
}else{
717+
processSchema(schema,file);
718+
}
719+
}
720+
721+
private void processRefHeaders(Map<String, Header> headers, String $ref) {
722+
String file = $ref.split("#/")[0];
723+
for(Header header : headers.values()) {
724+
if (header.get$ref() != null) {
725+
RefFormat ref = computeRefFormat(header.get$ref());
726+
if (isAnExternalRefFormat(ref)) {
727+
processRefHeader(header, $ref);
728+
} else {
729+
processRefToExternalHeader(file + header.get$ref(), RefFormat.RELATIVE);
730+
}
731+
}
732+
}
733+
}
734+
735+
private void processRefLinks(Map<String, Link> links, String $ref) {
736+
String file = $ref.split("#/")[0];
737+
for(Link link : links.values()) {
738+
if (link.get$ref() != null) {
739+
RefFormat ref = computeRefFormat(link.get$ref());
740+
if (isAnExternalRefFormat(ref)) {
741+
processRefLink(link, $ref);
742+
} else {
743+
processRefToExternalLink(file + link.get$ref(), RefFormat.RELATIVE);
744+
}
745+
}
746+
}
747+
}
748+
694749
private void processRefSchema(Schema subRef, String externalFile) {
695750
RefFormat format = computeRefFormat(subRef.get$ref());
696751

@@ -716,6 +771,45 @@ protected String constructRef(Schema refProperty, String rootLocation) {
716771
return join(rootLocation, ref);
717772
}
718773

774+
private void processRefHeader(Header subRef, String externalFile) {
775+
RefFormat format = computeRefFormat(subRef.get$ref());
776+
777+
if (!isAnExternalRefFormat(format)) {
778+
subRef.set$ref(RefType.SCHEMAS.getInternalPrefix()+ processRefToExternalSchema(externalFile + subRef.get$ref(), RefFormat.RELATIVE));
779+
return;
780+
}
781+
String $ref = subRef.get$ref();
782+
String subRefExternalPath = getExternalPath(subRef.get$ref())
783+
.orElse(null);
784+
785+
if (format.equals(RefFormat.RELATIVE) && !Objects.equals(subRefExternalPath, externalFile)) {
786+
$ref = join(externalFile, subRef.get$ref());
787+
subRef.set$ref($ref);
788+
}else {
789+
processRefToExternalHeader($ref, format);
790+
}
791+
}
792+
793+
private void processRefLink(Link subRef, String externalFile) {
794+
RefFormat format = computeRefFormat(subRef.get$ref());
795+
796+
if (!isAnExternalRefFormat(format)) {
797+
subRef.set$ref(RefType.SCHEMAS.getInternalPrefix()+ processRefToExternalSchema(externalFile + subRef.get$ref(), RefFormat.RELATIVE));
798+
return;
799+
}
800+
String $ref = subRef.get$ref();
801+
String subRefExternalPath = getExternalPath(subRef.get$ref())
802+
.orElse(null);
803+
804+
if (format.equals(RefFormat.RELATIVE) && !Objects.equals(subRefExternalPath, externalFile)) {
805+
$ref = join(externalFile, subRef.get$ref());
806+
subRef.set$ref($ref);
807+
}else {
808+
processRefToExternalLink($ref, format);
809+
}
810+
}
811+
812+
719813
// visible for testing
720814
public static String join(String source, String fragment) {
721815
try {

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,6 +2046,34 @@ public void testIssue1063() {
20462046

20472047
}
20482048

2049+
@Test
2050+
public void testIssue1177(@Injectable final List<AuthorizationValue> auths) {
2051+
String path = "/issue-1177/swagger.yaml";
2052+
2053+
ParseOptions options = new ParseOptions();
2054+
options.setResolve(true);
2055+
options.setResolveFully(true);
2056+
2057+
OpenAPI openAPI = new OpenAPIV3Parser().readLocation(path, auths, options).getOpenAPI();
2058+
2059+
// $ref response with $ref header
2060+
ApiResponse petsListApiResponse = openAPI.getPaths().get("/update-pets").getPost().getResponses().get("200");
2061+
assertNotNull(petsListApiResponse);
2062+
2063+
Header sessionIdHeader = petsListApiResponse.getHeaders().get("x-session-id");
2064+
assertNotNull(sessionIdHeader);
2065+
2066+
Schema petsListSchema = openAPI.getComponents().getSchemas().get("PetsList");
2067+
assertNotNull(petsListSchema);
2068+
2069+
assertNotNull(openAPI.getComponents().getHeaders());
2070+
Header sessionIdHeaderComponent = openAPI.getComponents().getHeaders().get("x-session-id");
2071+
assertTrue(sessionIdHeader == sessionIdHeaderComponent);
2072+
2073+
assertTrue(petsListApiResponse.getContent().get("application/json").getSchema() == petsListSchema);
2074+
2075+
}
2076+
20492077
@Test
20502078
public void testResolveFullyMap() {
20512079
ParseOptions options = new ParseOptions();
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
openapi: "3.0.2"
2+
info:
3+
version: 15.3.0
4+
title: "Common Data Types"
5+
paths: {}
6+
components:
7+
schemas:
8+
PetsList:
9+
type: array
10+
items:
11+
$ref: '#/components/schemas/Pet'
12+
13+
Pet:
14+
type: object
15+
properties:
16+
petType:
17+
type: string
18+
breed:
19+
$ref: '#/components/schemas/Breed'
20+
21+
Breed:
22+
type: object
23+
properties:
24+
name:
25+
type: string
26+
family:
27+
type: string
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
openapi: "3.0.2"
2+
info:
3+
version: 15.3.0
4+
title: "Common Responses"
5+
paths: {}
6+
components:
7+
responses:
8+
PetsListResponse:
9+
description: returns a list of pets
10+
headers:
11+
x-session-id:
12+
$ref: '../../headers/common-headers.yaml#/components/headers/x-session-id'
13+
content:
14+
application/json:
15+
schema:
16+
$ref: '../common-types.yaml#/components/schemas/PetsList'
17+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
openapi: "3.0.2"
2+
info:
3+
version: 15.3.0
4+
title: "Common Headers"
5+
paths: {}
6+
components:
7+
headers:
8+
x-session-id:
9+
schema:
10+
type: string
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
openapi: "3.0.2"
2+
info:
3+
version: 15.3.0
4+
title: test
5+
paths:
6+
/update-pets:
7+
post:
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
$ref: 'common/common-types.yaml#/components/schemas/PetsList'
13+
responses:
14+
'200':
15+
$ref: 'common/responses/common-responses.yaml#/components/responses/PetsListResponse'
16+

0 commit comments

Comments
 (0)