Skip to content

Commit 811d2f1

Browse files
authored
Merge pull request #2820 from swagger-api/ticket-2809
Refs #2809 - Allows filtering of specific definitions in SpecFilter.
2 parents 62912a1 + 7d6dd87 commit 811d2f1

File tree

5 files changed

+308
-0
lines changed

5 files changed

+308
-0
lines changed

modules/swagger-core/src/main/java/io/swagger/core/filter/AbstractSpecFilter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ public boolean isParamAllowed(
2929
return true;
3030
}
3131

32+
public boolean isDefinitionAllowed(
33+
Model model,
34+
Map<String, List<String>> params,
35+
Map<String, String> cookies,
36+
Map<String, List<String>> headers) {
37+
return true;
38+
}
39+
3240
public boolean isPropertyAllowed(
3341
Model model,
3442
Property property,

modules/swagger-core/src/main/java/io/swagger/core/filter/SpecFilter.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import io.swagger.models.properties.MapProperty;
1717
import io.swagger.models.properties.Property;
1818
import io.swagger.models.properties.RefProperty;
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
1921

2022
import java.util.ArrayList;
2123
import java.util.Arrays;
@@ -30,6 +32,9 @@
3032
import java.util.TreeSet;
3133

3234
public class SpecFilter {
35+
36+
Logger LOGGER = LoggerFactory.getLogger(SpecFilter.class);
37+
3338
public Swagger filter(Swagger swagger, SwaggerSpecFilter filter, Map<String, List<String>> params, Map<String, String> cookies, Map<String, List<String>> headers) {
3439
Swagger clone = new Swagger();
3540
clone.info(swagger.getInfo())
@@ -211,6 +216,21 @@ public Map<String, Model> filterDefinitions(SwaggerSpecFilter filter, Map<String
211216

212217
for (String key : definitions.keySet()) {
213218
Model definition = definitions.get(key);
219+
220+
// isDefinitionAllowed is not defined in SwaggerSpecFilter to avoid breaking compatibility with
221+
// existing client filters directly implementing SwaggerSpecFilter.
222+
if (filter instanceof AbstractSpecFilter) {
223+
boolean shouldIncludeDefinition = true;
224+
try {
225+
shouldIncludeDefinition = ((AbstractSpecFilter)filter).isDefinitionAllowed(definition, params, cookies, headers);
226+
} catch (Exception e) {
227+
LOGGER.error("Exception in filter implementation of `isDefinitionAllowed`; ignoring filter", e);
228+
}
229+
if (!shouldIncludeDefinition) {
230+
continue;
231+
}
232+
}
233+
214234
Map<String, Property> clonedProperties = new LinkedHashMap<String, Property>();
215235
if (definition.getProperties() != null) {
216236
for (String propName : definition.getProperties().keySet()) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.swagger.filter;
2+
3+
import io.swagger.core.filter.AbstractSpecFilter;
4+
import io.swagger.models.Model;
5+
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
/**
10+
* signals to remove unreferenced definitions.
11+
**/
12+
public class DefinitionAllowedFilter extends AbstractSpecFilter {
13+
14+
@Override
15+
public boolean isDefinitionAllowed(Model model, Map<String, List<String>> params, Map<String, String> cookies, Map<String, List<String>> headers) {
16+
if (model.getProperties() != null && model.getProperties().containsKey("hidden")) {
17+
return false;
18+
}
19+
return super.isDefinitionAllowed(model, params, cookies, headers);
20+
}
21+
22+
}

modules/swagger-core/src/test/java/io/swagger/filter/SpecFilterTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,24 @@ public void filterAwayBrokenReferenceModelProperties() throws IOException {
196196

197197
}
198198

199+
@Test(description = "it should filter away specific definitions")
200+
public void filterAwayDefinition() throws IOException {
201+
final Swagger swagger = getSwagger("specFiles/filteredDefinition.json");
202+
203+
assertNotNull(swagger.getDefinitions().get("User"));
204+
205+
final NoOpOperationsFilter noOpfilter = new NoOpOperationsFilter();
206+
Swagger filtered = new SpecFilter().filter(swagger, noOpfilter, null, null, null);
207+
208+
assertNotNull(filtered.getDefinitions().get("User"));
209+
210+
final DefinitionAllowedFilter refFilter = new DefinitionAllowedFilter();
211+
filtered = new SpecFilter().filter(swagger, refFilter, null, null, null);
212+
213+
assertNull(filtered.getDefinitions().get("User"));
214+
215+
}
216+
199217
@Test(description = "it should retain non-broken reference model properties")
200218
public void retainNonBrokenReferenceModelProperties() throws IOException {
201219
final Swagger swagger = getSwagger("specFiles/paramAndResponseRefArray.json");
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
{
2+
"swagger": "2.0",
3+
"title": "Petstore Sample API",
4+
"info": {
5+
"description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
6+
"title": "Petstore Sample API",
7+
"contact": {
8+
"name": "Swagger API Team"
9+
},
10+
"license": {
11+
"name": "MIT",
12+
"url": "http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT"
13+
}
14+
},
15+
"tags": [
16+
{
17+
"name": "pet",
18+
"description": "Everything about your Pets",
19+
"externalDocs": {
20+
"description": "Find out more",
21+
"url": "http://swagger.io"
22+
}
23+
},
24+
{
25+
"name": "user",
26+
"description": "Operations about user"
27+
},
28+
{
29+
"name": "store",
30+
"description": "Access to Petstore orders",
31+
"externalDocs": {
32+
"description": "Find out more",
33+
"url": "http://swagger.io"
34+
}
35+
}
36+
],
37+
"host": "petstore.swagger.io",
38+
"basePath": "/api",
39+
"paths": {
40+
"/pet": {
41+
"parameters": [
42+
{
43+
"name": "body",
44+
"in": "body",
45+
"description": "Pet object that needs to be added to the store",
46+
"required": false,
47+
"schema": {
48+
"$ref": "#/definitions/Pet"
49+
}
50+
}
51+
],
52+
"get": {
53+
"tags": [
54+
"pet"
55+
],
56+
"parameters": [
57+
{
58+
"name": "petId",
59+
"in": "path",
60+
"description": "ID of pet to fetch",
61+
"required": true,
62+
"type": "string"
63+
}
64+
],
65+
"responses": {
66+
"200": {
67+
"description": "found it",
68+
"schema": {
69+
"$ref": "#/definitions/User"
70+
}
71+
},
72+
"404": {
73+
"description": "Order not found"
74+
},
75+
"400": {
76+
"description": "Invalid ID supplied"
77+
}
78+
}
79+
},
80+
"put": {
81+
"tags": [
82+
"pet"
83+
],
84+
"parameters": [
85+
{
86+
"name": "body",
87+
"in": "body",
88+
"description": "Pet object that needs to be added to the store",
89+
"required": false,
90+
"schema": {
91+
"$ref": "#/definitions/Pet"
92+
}
93+
}
94+
],
95+
"responses": {
96+
"405": {
97+
"$ref": "http://my.company.com/responses/errors.json#/method-not-allowed"
98+
},
99+
"404": {
100+
"$ref": "http://my.company.com/responses/errors.json#/not-found"
101+
},
102+
"400": {
103+
"description": "Bad request"
104+
}
105+
}
106+
}
107+
}
108+
},
109+
"definitions": {
110+
"User": {
111+
"properties": {
112+
"id": {
113+
"type": "integer",
114+
"format": "int32"
115+
},
116+
"lastName": {
117+
"type": "string"
118+
},
119+
"hidden": {
120+
"type": "boolean"
121+
},
122+
"username": {
123+
"type": "string"
124+
},
125+
"phone": {
126+
"type": "string"
127+
},
128+
"email": {
129+
"type": "string"
130+
},
131+
"userStatus": {
132+
"type": "integer",
133+
"format": "int32"
134+
},
135+
"firstName": {
136+
"type": "string"
137+
},
138+
"password": {
139+
"type": "string"
140+
}
141+
}
142+
},
143+
"Category": {
144+
"properties": {
145+
"id": {
146+
"type": "integer",
147+
"format": "int32"
148+
},
149+
"name": {
150+
"type": "string"
151+
}
152+
}
153+
},
154+
"Pet": {
155+
"properties": {
156+
"id": {
157+
"type": "integer",
158+
"format": "int32"
159+
},
160+
"tags": {
161+
"type": "array",
162+
"items": {
163+
"$ref": "#/definitions/Tag"
164+
}
165+
},
166+
"category": {
167+
"$ref": "#/definitions/Category"
168+
},
169+
"status": {
170+
"type": "string"
171+
},
172+
"name": {
173+
"type": "string"
174+
},
175+
"photoUrls": {
176+
"type": "array",
177+
"items": {
178+
"type": "string"
179+
}
180+
}
181+
}
182+
},
183+
"Tag": {
184+
"properties": {
185+
"id": {
186+
"type": "integer",
187+
"format": "int32"
188+
},
189+
"name": {
190+
"type": "string"
191+
}
192+
}
193+
},
194+
"Order": {
195+
"properties": {
196+
"id": {
197+
"type": "integer",
198+
"format": "int32"
199+
},
200+
"orderTag": {
201+
"$ref": "#/definitions/OrderTag"
202+
},
203+
"tag": {
204+
"$ref": "#/definitions/Tag"
205+
},
206+
"petId": {
207+
"type": "integer",
208+
"format": "int32"
209+
},
210+
"status": {
211+
"type": "string"
212+
},
213+
"complete": {
214+
"type": "boolean"
215+
},
216+
"quantity": {
217+
"type": "integer",
218+
"format": "int32"
219+
},
220+
"shipDate": {
221+
"type": "string",
222+
"format": "date-time"
223+
}
224+
}
225+
},
226+
"NoPropertiesModel": {
227+
},
228+
"OrderTag": {
229+
"properties": {
230+
"id": {
231+
"type": "integer",
232+
"format": "int32"
233+
},
234+
"name": {
235+
"type": "string"
236+
}
237+
}
238+
}
239+
}
240+
}

0 commit comments

Comments
 (0)