Skip to content

Commit a57f87d

Browse files
author
bnasslahsen
committed
Improve support of Webflux with Functional Endpoints
1 parent e7483a8 commit a57f87d

File tree

9 files changed

+343
-56
lines changed

9 files changed

+343
-56
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,11 @@ protected void calculatePath(List<RouterOperation> routerOperationList) {
295295
LOGGER.error(e.getMessage());
296296
}
297297
if (handlerMethod != null && isPackageToScan(handlerMethod.getBeanType().getPackage()) && isPathToMatch(routerOperation.getPath()))
298-
calculatePath(handlerMethod, routerOperation.getPath(), new HashSet<>(Arrays.asList(routerOperation.getMethod())), routerOperation.getOperation(), routerOperation.getConsumes(), routerOperation.getProduces(), routerOperation.getHeaders());
298+
calculatePath(handlerMethod, routerOperation.getPath(), new HashSet<>(Arrays.asList(routerOperation.getMethods())), routerOperation.getOperation(), routerOperation.getConsumes(), routerOperation.getProduces(), routerOperation.getHeaders());
299299
}
300300
}
301301
else if (StringUtils.isNotBlank(routerOperation.getOperation().operationId()) && isPathToMatch(routerOperation.getPath())) {
302-
calculatePath(routerOperation.getPath(), new HashSet<>(Arrays.asList(routerOperation.getMethod())), routerOperation.getOperation(), routerOperation.getConsumes(), routerOperation.getProduces(), routerOperation.getHeaders());
302+
calculatePath(routerOperation.getPath(), new HashSet<>(Arrays.asList(routerOperation.getMethods())), routerOperation.getOperation(), routerOperation.getConsumes(), routerOperation.getProduces(), routerOperation.getHeaders());
303303
}
304304
}
305305
}
@@ -506,30 +506,30 @@ protected void mergeRouters(List<RouterFunctionData> routerFunctionDatas, List<o
506506
.collect(Collectors.toList());
507507
if (routerFunctionDataList.size() == 1)
508508
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
509-
else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperation.getMethod())) {
509+
else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperation.getMethods())) {
510510
// PATH + METHOD
511511
routerFunctionDataList = routerFunctionDatas.stream()
512512
.filter(routerFunctionData1 -> routerFunctionData1.getPath().equals(routerOperation.getPath())
513-
&& routerFunctionData1.getMethods()[0].equals(routerOperation.getMethod()[0]))
513+
&& isEqualMethods(routerOperation.getMethods(), routerFunctionData1.getMethods()))
514514
.collect(Collectors.toList());
515515
if (routerFunctionDataList.size() == 1)
516516
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
517517
else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperation.getProduces())) {
518518
// PATH + METHOD + PRODUCES
519519
routerFunctionDataList = routerFunctionDatas.stream()
520520
.filter(routerFunctionData1 -> routerFunctionData1.getPath().equals(routerOperation.getPath())
521-
&& routerFunctionData1.getMethods()[0].equals(routerOperation.getMethod()[0])
522-
&& routerFunctionData1.getProduces()[0].equals(routerOperation.getProduces()[0]))
521+
&& isEqualMethods(routerOperation.getMethods(), routerFunctionData1.getMethods())
522+
&& isEqualArrays(routerFunctionData1.getProduces(), routerOperation.getProduces()))
523523
.collect(Collectors.toList());
524524
if (routerFunctionDataList.size() == 1)
525525
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
526526
else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperation.getConsumes())) {
527527
// PATH + METHOD + PRODUCES + CONSUMES
528528
routerFunctionDataList = routerFunctionDatas.stream()
529529
.filter(routerFunctionData1 -> routerFunctionData1.getPath().equals(routerOperation.getPath())
530-
&& routerFunctionData1.getMethods()[0].equals(routerOperation.getMethod()[0])
531-
&& routerFunctionData1.getProduces()[0].equals(routerOperation.getProduces()[0])
532-
&& routerFunctionData1.getConsumes()[0].equals(routerOperation.getConsumes()[0]))
530+
&& isEqualMethods(routerOperation.getMethods(), routerFunctionData1.getMethods())
531+
&& isEqualArrays(routerFunctionData1.getProduces(), routerOperation.getProduces())
532+
&& isEqualArrays(routerFunctionData1.getConsumes(), routerOperation.getConsumes()))
533533
.collect(Collectors.toList());
534534
if (routerFunctionDataList.size() == 1)
535535
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
@@ -539,8 +539,8 @@ else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperat
539539
// PATH + METHOD + CONSUMES
540540
routerFunctionDataList = routerFunctionDatas.stream()
541541
.filter(routerFunctionData1 -> routerFunctionData1.getPath().equals(routerOperation.getPath())
542-
&& routerFunctionData1.getMethods()[0].equals(routerOperation.getMethod()[0])
543-
&& routerFunctionData1.getConsumes()[0].equals(routerOperation.getConsumes()[0]))
542+
&& isEqualMethods(routerOperation.getMethods(), routerFunctionData1.getMethods())
543+
&& isEqualArrays(routerFunctionData1.getConsumes(), routerOperation.getConsumes()))
544544
.collect(Collectors.toList());
545545
if (routerFunctionDataList.size() == 1)
546546
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
@@ -550,17 +550,17 @@ else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperat
550550
// PATH + PRODUCES
551551
routerFunctionDataList = routerFunctionDatas.stream()
552552
.filter(routerFunctionData1 -> routerFunctionData1.getPath().equals(routerOperation.getPath())
553-
&& routerFunctionData1.getProduces()[0].equals(routerOperation.getProduces()[0]))
553+
&& isEqualArrays(routerFunctionData1.getProduces(), routerOperation.getProduces()))
554554
.collect(Collectors.toList());
555555
if (routerFunctionDataList.size() == 1)
556556
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
557557
else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperation.getConsumes())) {
558558
// PATH + PRODUCES + CONSUMES
559559
routerFunctionDataList = routerFunctionDatas.stream()
560560
.filter(routerFunctionData1 -> routerFunctionData1.getPath().equals(routerOperation.getPath())
561-
&& routerFunctionData1.getMethods()[0].equals(routerOperation.getMethod()[0])
562-
&& routerFunctionData1.getConsumes()[0].equals(routerOperation.getConsumes()[0])
563-
&& routerFunctionData1.getProduces()[0].equals(routerOperation.getProduces()[0]))
561+
&& isEqualMethods(routerOperation.getMethods(), routerFunctionData1.getMethods())
562+
&& isEqualArrays(routerFunctionData1.getConsumes(), routerOperation.getConsumes())
563+
&& isEqualArrays(routerFunctionData1.getProduces(), routerOperation.getProduces()))
564564
.collect(Collectors.toList());
565565
if (routerFunctionDataList.size() == 1)
566566
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
@@ -570,7 +570,7 @@ else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperat
570570
// PATH + CONSUMES
571571
routerFunctionDataList = routerFunctionDatas.stream()
572572
.filter(routerFunctionData1 -> routerFunctionData1.getPath().equals(routerOperation.getPath())
573-
&& routerFunctionData1.getConsumes()[0].equals(routerOperation.getConsumes()[0]))
573+
&& isEqualArrays(routerFunctionData1.getConsumes(), routerOperation.getConsumes()))
574574
.collect(Collectors.toList());
575575
if (routerFunctionDataList.size() == 1)
576576
fillRouterOperation(routerFunctionDataList.get(0), routerOperation);
@@ -579,15 +579,27 @@ else if (routerFunctionDataList.size() > 1 && ArrayUtils.isNotEmpty(routerOperat
579579
}
580580
}
581581

582+
private boolean isEqualArrays(String[] array1, String[] array2) {
583+
Arrays.sort(array1);
584+
Arrays.sort(array2);
585+
return Arrays.equals(array1,array2);
586+
}
587+
588+
private boolean isEqualMethods(RequestMethod[] requestMethods1, RequestMethod[] requestMethods2) {
589+
Arrays.sort(requestMethods1);
590+
Arrays.sort(requestMethods2);
591+
return Arrays.equals(requestMethods1,requestMethods2);
592+
}
593+
582594
private void fillRouterOperation(RouterFunctionData routerFunctionData, org.springdoc.core.models.RouterOperation routerOperation) {
583595
if (ArrayUtils.isEmpty(routerOperation.getConsumes()))
584596
routerOperation.setConsumes(routerFunctionData.getConsumes());
585597
if (ArrayUtils.isEmpty(routerOperation.getProduces()))
586598
routerOperation.setProduces(routerFunctionData.getProduces());
587599
if (ArrayUtils.isEmpty(routerOperation.getHeaders()))
588600
routerOperation.setHeaders(routerFunctionData.getHeaders());
589-
if (ArrayUtils.isEmpty(routerOperation.getMethod()))
590-
routerOperation.setMethod(routerFunctionData.getMethods());
601+
if (ArrayUtils.isEmpty(routerOperation.getMethods()))
602+
routerOperation.setMethods(routerFunctionData.getMethods());
591603
}
592604

593605
}

springdoc-openapi-common/src/main/java/org/springdoc/core/models/RouterFunctionData.java

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
package org.springdoc.core.models;
2222

23+
import java.util.ArrayList;
24+
import java.util.List;
2325
import java.util.Set;
2426

2527
import org.apache.commons.lang3.ArrayUtils;
@@ -33,11 +35,11 @@ public class RouterFunctionData {
3335

3436
private String path;
3537

36-
private String[] consumes;
38+
private List<String> consumes = new ArrayList<>();
3739

38-
private String[] produces;
40+
private List<String> produces = new ArrayList<>();
3941

40-
private String[] headers;
42+
private List<String> headers = new ArrayList<>();
4143

4244
private String queryParam;
4345

@@ -60,46 +62,34 @@ public void setQueryParam(String queryParam) {
6062
}
6163

6264
public String[] getHeaders() {
63-
return headers;
65+
return headers.toArray(new String[headers.size()]);
6466
}
6567

66-
public void setHeaders(String[] headers) {
67-
this.headers = headers;
68-
}
69-
70-
public void setHeaders(String headers) {
68+
public void addHeaders(String headers) {
7169
if (StringUtils.isNotBlank(headers))
72-
this.headers = new String[] { headers };
70+
this.headers.add(headers);
7371
}
7472

7573
public RequestMethod[] getMethods() {
7674
return methods;
7775
}
7876

79-
public void setMethods(RequestMethod[] methods) {
80-
this.methods = methods;
81-
}
82-
8377
public void setMethods(Set<HttpMethod> methods) {
8478
this.methods = getMethod(methods);
8579
}
8680

8781
public String[] getConsumes() {
88-
return consumes;
82+
return consumes.toArray(new String[consumes.size()]);
8983
}
9084

91-
public void setConsumes(String[] consumes) {
92-
this.consumes = consumes;
93-
}
94-
95-
public void setConsumes(String consumes) {
85+
public void addConsumes(String consumes) {
9686
if (StringUtils.isNotBlank(consumes))
97-
this.consumes = new String[] { consumes };
87+
this.consumes.add(consumes);
9888
}
9989

100-
public void setProduces(String produces) {
90+
public void addProduces(String produces) {
10191
if (StringUtils.isNotBlank(produces))
102-
this.produces = new String[] { produces };
92+
this.produces.add(produces);
10393
}
10494

10595
private RequestMethod[] getMethod(Set<HttpMethod> methods) {
@@ -110,11 +100,7 @@ private RequestMethod[] getMethod(Set<HttpMethod> methods) {
110100
}
111101

112102
public String[] getProduces() {
113-
return produces;
114-
}
115-
116-
public void setProduces(String[] produces) {
117-
this.produces = produces;
103+
return produces.toArray(new String[produces.size()]);
118104
}
119105

120106
private RequestMethod getRequestMethod(HttpMethod httpMethod) {

springdoc-openapi-common/src/main/java/org/springdoc/core/models/RouterOperation.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class RouterOperation {
3131

3232
private String path;
3333

34-
private RequestMethod[] method;
34+
private RequestMethod[] methods;
3535

3636
private String[] consumes;
3737

@@ -49,7 +49,7 @@ public class RouterOperation {
4949

5050
public RouterOperation(org.springdoc.core.annotations.RouterOperation routerOperationAnnotation) {
5151
this.path = routerOperationAnnotation.path();
52-
this.method = routerOperationAnnotation.method();
52+
this.methods = routerOperationAnnotation.method();
5353
this.consumes = routerOperationAnnotation.consumes();
5454
this.produces = routerOperationAnnotation.produces();
5555
this.beanClass = routerOperationAnnotation.beanClass();
@@ -61,7 +61,7 @@ public RouterOperation(org.springdoc.core.annotations.RouterOperation routerOper
6161

6262
public RouterOperation(org.springdoc.core.annotations.RouterOperation routerOperationAnnotation, RouterFunctionData routerFunctionData) {
6363
this.path = StringUtils.isBlank(routerOperationAnnotation.path()) ? routerFunctionData.getPath() : routerOperationAnnotation.path();
64-
this.method = ArrayUtils.isEmpty(routerOperationAnnotation.method()) ? routerFunctionData.getMethods() : routerOperationAnnotation.method();
64+
this.methods = ArrayUtils.isEmpty(routerOperationAnnotation.method()) ? routerFunctionData.getMethods() : routerOperationAnnotation.method();
6565
this.consumes = ArrayUtils.isEmpty(routerOperationAnnotation.consumes()) ? routerFunctionData.getConsumes() : routerOperationAnnotation.consumes();
6666
this.produces = ArrayUtils.isEmpty(routerOperationAnnotation.produces()) ? routerFunctionData.getProduces() : routerOperationAnnotation.produces();
6767
this.beanClass = routerOperationAnnotation.beanClass();
@@ -80,12 +80,12 @@ public void setPath(String path) {
8080
this.path = path;
8181
}
8282

83-
public RequestMethod[] getMethod() {
84-
return method;
83+
public RequestMethod[] getMethods() {
84+
return methods;
8585
}
8686

87-
public void setMethod(RequestMethod[] method) {
88-
this.method = method;
87+
public void setMethods(RequestMethod[] methods) {
88+
this.methods = methods;
8989
}
9090

9191
public String[] getConsumes() {

springdoc-openapi-common/src/main/java/org/springdoc/core/visitor/AbstractRouterFunctionVisitor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ public void path(String pattern) {
4545

4646
public void header(String name, String value) {
4747
if (HttpHeaders.ACCEPT.equals(name))
48-
routerFunctionData.setProduces(value);
48+
routerFunctionData.addProduces(value);
4949
else if (HttpHeaders.CONTENT_TYPE.equals(name))
50-
routerFunctionData.setConsumes(value);
50+
routerFunctionData.addConsumes(value);
5151
else
52-
routerFunctionData.setHeaders(name + "=" + value);
52+
routerFunctionData.addHeaders(name + "=" + value);
5353
}
5454

5555
public List<RouterFunctionData> getRouterFunctionDatas() {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
*
3+
* *
4+
* * * Copyright 2019-2020 the original author or authors.
5+
* * *
6+
* * * Licensed under the Apache License, Version 2.0 (the "License");
7+
* * * you may not use this file except in compliance with the License.
8+
* * * You may obtain a copy of the License at
9+
* * *
10+
* * * https://www.apache.org/licenses/LICENSE-2.0
11+
* * *
12+
* * * Unless required by applicable law or agreed to in writing, software
13+
* * * distributed under the License is distributed on an "AS IS" BASIS,
14+
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* * * See the License for the specific language governing permissions and
16+
* * * limitations under the License.
17+
* *
18+
*
19+
*/
20+
21+
package test.org.springdoc.api.app74;
22+
23+
public class Book {
24+
25+
private String id;
26+
private String title;
27+
private String author;
28+
29+
public Book(String id, String title, String author) {
30+
this.id = id;
31+
this.title = title;
32+
this.author = author;
33+
}
34+
35+
public String getId() {
36+
return id;
37+
}
38+
39+
public void setId(String id) {
40+
this.id = id;
41+
}
42+
43+
public String getTitle() {
44+
return title;
45+
}
46+
47+
public void setTitle(String title) {
48+
this.title = title;
49+
}
50+
51+
public String getAuthor() {
52+
return author;
53+
}
54+
55+
public void setAuthor(String author) {
56+
this.author = author;
57+
}
58+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
*
3+
* *
4+
* * * Copyright 2019-2020 the original author or authors.
5+
* * *
6+
* * * Licensed under the Apache License, Version 2.0 (the "License");
7+
* * * you may not use this file except in compliance with the License.
8+
* * * You may obtain a copy of the License at
9+
* * *
10+
* * * https://www.apache.org/licenses/LICENSE-2.0
11+
* * *
12+
* * * Unless required by applicable law or agreed to in writing, software
13+
* * * distributed under the License is distributed on an "AS IS" BASIS,
14+
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* * * See the License for the specific language governing permissions and
16+
* * * limitations under the License.
17+
* *
18+
*
19+
*/
20+
21+
package test.org.springdoc.api.app74;
22+
23+
import reactor.core.publisher.Flux;
24+
25+
import org.springframework.stereotype.Component;
26+
27+
@Component
28+
public class BookRepository {
29+
30+
31+
Flux<Book> findByAuthor(String author){
32+
return Flux.just(new Book("1", "title1","author1"));
33+
}
34+
35+
Flux<Book> findAll() {
36+
return Flux.just(new Book("2", "title2","author2"));
37+
}
38+
}

0 commit comments

Comments
 (0)