Skip to content

Commit 1f2fe7b

Browse files
committed
Fix URISyntaxException while reading OpenAPI 3.1 from windows file path location
1 parent 20de7a2 commit 1f2fe7b

File tree

3 files changed

+267
-11
lines changed

3 files changed

+267
-11
lines changed

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ public SwaggerParseResult readWithInfo(String location, List<AuthorizationValue>
207207

208208
private SwaggerParseResult resolve(SwaggerParseResult result, List<AuthorizationValue> auth, ParseOptions options,
209209
String location) {
210+
if (location != null) {
211+
location = location.replace('\\', '/');
212+
}
210213
try {
211214
if (options != null) {
212215
if (options.isResolve() || options.isResolveFully()) {
@@ -284,7 +287,7 @@ private ObjectMapper getRightMapper(String data) {
284287
}
285288

286289
private String readContentFromLocation(String location, List<AuthorizationValue> auth) {
287-
final String adjustedLocation = location.replaceAll("\\\\", "/");
290+
final String adjustedLocation = location.replace('\\', '/');
288291
try {
289292
if (adjustedLocation.toLowerCase().startsWith("http")) {
290293
return RemoteUrl.urlToString(adjustedLocation, auth);

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343
public class OpenAPIV3ParserTest {
4444
List<AuthorizationValue> auths = new ArrayList<>();
4545

46+
@Test(description = "Issue 2223: reading 3.1 spec from Windows file path location produces URISyntaxException" )
47+
public void testWindowsFilePathRead() {
48+
OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
49+
OpenAPI openAPI = openApiParser.read("\\issue-2223\\openapi.yaml");
50+
assertNotNull(openAPI, "OpenAPI object should not be null (no errors during read())");
51+
}
52+
4653
@Test
4754
public void testFailedToResolveResponseReferences() {
4855
OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
@@ -51,7 +58,7 @@ public void testFailedToResolveResponseReferences() {
5158
SwaggerParseResult parseResult = openApiParser.readLocation("issue-2037/openapi.yaml", null, options);
5259
OpenAPI openAPI = parseResult.getOpenAPI();
5360

54-
Assert.assertTrue(openAPI.getPaths().get("/get").get$ref() == null);
61+
assertNull(openAPI.getPaths().get("/get").get$ref());
5562
Assert.assertEquals(openAPI.getPaths().get("/get").getGet().getResponses().get("200").getContent().get("application/json").getSchema().get$ref(), "#/components/schemas/ResponsesRef");
5663
}
5764

@@ -64,13 +71,13 @@ public void testFailedToResolveExternalReferences() {
6471
SwaggerParseResult parseResult = openApiParser.readLocation("resolve-external-ref/failedToResolveExternalRefs.yaml", null, options);
6572
OpenAPI openAPI = parseResult.getOpenAPI();
6673

67-
Assert.assertTrue(openAPI.getPaths().get("/permAssignments").get$ref() == null);
68-
Assert.assertEquals(openAPI.getPaths().get("/permAssignments").getGet().getResponses().get("202").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/schemaResponseSuccess");
69-
Assert.assertTrue(openAPI.getPaths().get("/permAssignmentChangeRequests").get$ref() == null);
70-
Assert.assertEquals(openAPI.getPaths().get("/permAssignmentChangeRequests").getGet().getResponses().get("202").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/schemaResponseSuccess");
71-
Assert.assertTrue(openAPI.getPaths().get("/permAssignmentChange").get$ref() == null);
72-
Assert.assertEquals(openAPI.getPaths().get("/permAssignmentChange").getGet().getResponses().get("201").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/Error");
73-
Assert.assertEquals(openAPI.getPaths().get("/permAssignmentChange").getGet().getResponses().get("404").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/RemoteError");
74+
assertNull(openAPI.getPaths().get("/permAssignments").get$ref());
75+
assertEquals(openAPI.getPaths().get("/permAssignments").getGet().getResponses().get("202").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/schemaResponseSuccess");
76+
assertNull(openAPI.getPaths().get("/permAssignmentChangeRequests").get$ref());
77+
assertEquals(openAPI.getPaths().get("/permAssignmentChangeRequests").getGet().getResponses().get("202").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/schemaResponseSuccess");
78+
assertNull(openAPI.getPaths().get("/permAssignmentChange").get$ref());
79+
assertEquals(openAPI.getPaths().get("/permAssignmentChange").getGet().getResponses().get("201").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/Error");
80+
assertEquals(openAPI.getPaths().get("/permAssignmentChange").getGet().getResponses().get("404").getContent().get("application/vnd.api+json").getSchema().get$ref(),"#/components/schemas/RemoteError");
7481

7582
}
7683

@@ -2188,7 +2195,7 @@ public void testIssue393() {
21882195
}
21892196

21902197
@Test
2191-
public void testBadFormat() throws Exception {
2198+
public void testBadFormat() {
21922199
OpenAPIV3Parser parser = new OpenAPIV3Parser();
21932200
final OpenAPI openAPI = parser.read("src/test/resources/bad_format.yaml");
21942201

@@ -3429,4 +3436,4 @@ public void testVersion(){
34293436
SwaggerParseResult parseResult = openApiParser.readLocation("version-missing.yaml", null, options);
34303437
assertEquals(parseResult.getMessages().get(0), "attribute info.version is missing");
34313438
}
3432-
}
3439+
}
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
openapi: 3.1.1
2+
info:
3+
title: Ferguson Customer Public API
4+
description: Services that provide access to Ferguson's customer information
5+
contact:
6+
name: Ferguson Middleware Services team
7+
license:
8+
name: Ferguson Services
9+
url: 'https://ferguson.com/licenses/LICENSE-1.0.html'
10+
version: v1.0
11+
servers:
12+
- url: https://localhost:8083/customer-publicapi-v1/svc
13+
description: Development
14+
tags:
15+
- name: domain
16+
description: Customer
17+
- name: visibility
18+
description: public
19+
paths:
20+
/{mainCustomerId}/billToZip/{billToZipCode}:
21+
get:
22+
operationId: getMainCustomerInfoBillZipcode
23+
summary: Service to get Customer information from main Customer account and associated billTo zipcode
24+
description: Service to get related Customer information
25+
parameters:
26+
- $ref: '#/components/parameters/transId'
27+
- $ref: '#/components/parameters/mainCustomerId'
28+
- $ref: '#/components/parameters/billToZipCode'
29+
30+
responses:
31+
'200':
32+
description: Request Successful
33+
headers:
34+
trans-id:
35+
$ref: '#/components/headers/trans-id'
36+
content:
37+
application/json:
38+
schema:
39+
$ref: '#/components/schemas/customerInfoResponse'
40+
41+
'400':
42+
description: Bad request
43+
headers:
44+
trans-id:
45+
$ref: '#/components/headers/trans-id'
46+
content:
47+
application/json:
48+
schema:
49+
$ref: '#/components/schemas/validationErrors'
50+
51+
'404':
52+
description: Not Found
53+
headers:
54+
trans-id:
55+
$ref: '#/components/headers/trans-id'
56+
'500':
57+
description: Internal Error
58+
headers:
59+
trans-id:
60+
$ref: '#/components/headers/trans-id'
61+
fe-resp-code:
62+
$ref: '#/components/headers/fe-resp-code'
63+
fe-resp-msg:
64+
$ref: '#/components/headers/fe-resp-msg'
65+
66+
components:
67+
schemas:
68+
regionId:
69+
type: string
70+
description: Region Id
71+
example: "RICH"
72+
branchId:
73+
type: string
74+
description: Branch Id
75+
example: "1350"
76+
customerType:
77+
type: string
78+
enum:
79+
- MASTER
80+
- MAIN
81+
- JOB
82+
customerName:
83+
type: string
84+
description: Account name
85+
example: "WP CLARKS FARM LLC"
86+
contractIds:
87+
type: array
88+
items:
89+
type: string
90+
description: Contract Id
91+
customerNumber:
92+
type: string
93+
description: Customer Id
94+
example: "276962"
95+
jobName:
96+
type: string
97+
description: Job name
98+
example: "OTIS HATFIELD"
99+
jobNumber:
100+
type: string
101+
description: Customer Id of the Job
102+
example: "93738"
103+
billingAddress:
104+
description: Billing address of the account
105+
type: object
106+
properties:
107+
streets:
108+
title: Line(s) of Street Address
109+
type: array
110+
items:
111+
type: string
112+
example: "1250 W. Mockingbird Lane"
113+
city:
114+
title: City
115+
type: string
116+
example: "Newport News"
117+
state:
118+
title: State Code
119+
type: string
120+
example: VA
121+
postalCode:
122+
title: Postal Code
123+
type: string
124+
example: 23606
125+
126+
customerInfoResponse:
127+
title: Customer Info Response with master, main and job info
128+
type: object
129+
properties:
130+
masterCustomerNumber:
131+
type: string
132+
description: Master customer number
133+
example: '371394'
134+
customerType:
135+
$ref: '#/components/schemas/customerType'
136+
mainCustomers:
137+
type: array
138+
items:
139+
$ref: '#/components/schemas/mainCustomer'
140+
mainCustomer:
141+
type: object
142+
properties:
143+
customerType:
144+
$ref: '#/components/schemas/customerType'
145+
regionId:
146+
$ref: '#/components/schemas/regionId'
147+
branchId:
148+
$ref: '#/components/schemas/branchId'
149+
customerName:
150+
$ref: '#/components/schemas/customerName'
151+
contractIds:
152+
$ref: '#/components/schemas/contractIds'
153+
customerNumber:
154+
$ref: '#/components/schemas/customerNumber'
155+
billingAddress:
156+
type: array
157+
items:
158+
$ref: '#/components/schemas/billingAddress'
159+
mainCustomerJobs:
160+
type: array
161+
items:
162+
$ref: '#/components/schemas/mainCustomerJob'
163+
164+
mainCustomerJob:
165+
type: object
166+
properties:
167+
customerType:
168+
$ref: '#/components/schemas/customerType'
169+
regionId:
170+
$ref: '#/components/schemas/regionId'
171+
branchId:
172+
$ref: '#/components/schemas/branchId'
173+
jobName:
174+
$ref: '#/components/schemas/jobName'
175+
contractIds:
176+
$ref: '#/components/schemas/contractIds'
177+
jobNumber:
178+
$ref: '#/components/schemas/jobNumber'
179+
billingAddress:
180+
type: array
181+
items:
182+
$ref: '#/components/schemas/billingAddress'
183+
validationError:
184+
title: Parameter Validation Error
185+
type: object
186+
x-allArgsConstructor: true
187+
properties:
188+
errorCode:
189+
title: Error Code
190+
description: Error Code indicating the nature of the error.
191+
type: string
192+
example: dataerror.k8.app.zipcode.invalid
193+
errorMsg:
194+
title: Error Message
195+
description: Human readable message associated with the errorCode.
196+
type: string
197+
example: invalid zipcode format
198+
field:
199+
title: Parameter in Error
200+
type: string
201+
example: billToZipCode
202+
validationErrors:
203+
title: List of Validation Errors
204+
type: array
205+
minItems: 1
206+
items:
207+
$ref: '#/components/schemas/validationError'
208+
headers:
209+
fe-resp-code:
210+
schema:
211+
type: string
212+
example: severe.error
213+
description: Response code
214+
fe-resp-msg:
215+
schema:
216+
type: string
217+
example: Severe Error
218+
description: Response message
219+
trans-id:
220+
schema:
221+
type: string
222+
description: Transaction Id (passed in by consumer or generated by the service)
223+
224+
parameters:
225+
transId:
226+
name: trans-id
227+
in: header
228+
description: Transaction Id (Provided by service consumer)
229+
required: false
230+
schema:
231+
type: string
232+
mainCustomerId:
233+
name: mainCustomerId
234+
in: path
235+
description: Main Customer id
236+
required: true
237+
schema:
238+
type: string
239+
billToZipCode:
240+
name: billToZipCode
241+
in: path
242+
description: Billed to zip code associated with the Main Account
243+
required: true
244+
schema:
245+
type: string
246+
pattern: '^(\\d{5})([-\\s]*\\d{4})?$'

0 commit comments

Comments
 (0)