Skip to content

Commit 7e2749c

Browse files
committed
feat: Preserve OpenAPI extensions on Operation
1 parent 99601c8 commit 7e2749c

6 files changed

Lines changed: 38 additions & 4 deletions

File tree

src/main/java/com/retailsvc/http/spec/Operation.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ public record Operation(
1010
PathTemplate path,
1111
Optional<RequestBody> requestBody,
1212
List<Parameter> parameters,
13-
Map<String, Response> responses) {}
13+
Map<String, Response> responses,
14+
Map<String, Object> extensions) {}

src/main/java/com/retailsvc/http/spec/Spec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private static Operation parseOperation(
179179
.orElse(List.of());
180180
Map<String, Response> responses =
181181
parseResponses((Map<String, Object>) raw.getOrDefault("responses", Map.of()));
182-
return new Operation(opId, method, path, body, params, responses);
182+
return new Operation(opId, method, path, body, params, responses, extractExtensions(raw));
183183
}
184184

185185
private static Parameter resolveParameterOrParse(

src/test/java/com/retailsvc/http/internal/RequestPreparationFilterTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ void successPathBindsRequestContextDuringChain() throws Exception {
7171
PathTemplate.compile("/users/{id}"),
7272
Optional.empty(),
7373
List.of(),
74+
Map.of(),
7475
Map.of());
7576
Spec spec = specWith(op);
7677
Filter f = newFilter(spec);
@@ -106,6 +107,7 @@ void unknownPathThrowsNotFound() {
106107
PathTemplate.compile("/x"),
107108
Optional.empty(),
108109
List.of(),
110+
Map.of(),
109111
Map.of()));
110112
Filter f = newFilter(spec);
111113

@@ -124,6 +126,7 @@ void wrongMethodThrowsMethodNotAllowed() {
124126
PathTemplate.compile("/x"),
125127
Optional.empty(),
126128
List.of(),
129+
Map.of(),
127130
Map.of()));
128131
Filter f = newFilter(spec);
129132

@@ -142,6 +145,7 @@ void invalidQueryParamThrowsValidation() {
142145
PathTemplate.compile("/x"),
143146
Optional.empty(),
144147
List.of(new Parameter("q", Parameter.Location.QUERY, true, stringSchema)),
148+
Map.of(),
145149
Map.of());
146150
Spec spec = specWith(op);
147151
Filter f = newFilter(spec);

src/test/java/com/retailsvc/http/internal/RouterTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313
class RouterTest {
1414
private Operation op(String id, HttpMethod m, String path) {
15-
return new Operation(id, m, PathTemplate.compile(path), Optional.empty(), List.of(), Map.of());
15+
return new Operation(
16+
id, m, PathTemplate.compile(path), Optional.empty(), List.of(), Map.of(), Map.of());
1617
}
1718

1819
@Test

src/test/java/com/retailsvc/http/spec/ExtensionsTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,31 @@ void infoExtensionsExposeXKeys() {
5757
Spec spec = Spec.from(raw);
5858
assertThat(spec.info().extensions()).containsEntry("x-contact-team", "platform");
5959
}
60+
61+
@Test
62+
void operationExtensionsExposeXPermissions() {
63+
Map<String, Object> raw =
64+
Map.of(
65+
"openapi",
66+
"3.1.0",
67+
"info",
68+
Map.of("title", "t", "version", "1"),
69+
"servers",
70+
List.of(Map.of("url", "https://example.com")),
71+
"paths",
72+
Map.of(
73+
"/promotions",
74+
Map.of(
75+
"post",
76+
Map.of(
77+
"operationId",
78+
"createPromotion",
79+
"x-permissions",
80+
List.of("pro.promotion.create"),
81+
"responses",
82+
Map.of()))));
83+
Spec spec = Spec.from(raw);
84+
Operation op = spec.operations().getFirst();
85+
assertThat(op.extensions()).containsEntry("x-permissions", List.of("pro.promotion.create"));
86+
}
6087
}

src/test/java/com/retailsvc/http/spec/OperationTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ void operationCarriesAllFields() {
1818
new Parameter(
1919
"id", Parameter.Location.PATH, true, new BooleanSchema(Set.of(TypeName.BOOLEAN)));
2020
Operation op =
21-
new Operation("get-user", HttpMethod.GET, path, Optional.empty(), List.of(param), Map.of());
21+
new Operation(
22+
"get-user", HttpMethod.GET, path, Optional.empty(), List.of(param), Map.of(), Map.of());
2223
assertThat(op.operationId()).isEqualTo("get-user");
2324
assertThat(op.method()).isEqualTo(HttpMethod.GET);
2425
assertThat(op.parameters()).hasSize(1);

0 commit comments

Comments
 (0)