Skip to content

Commit 399e2e1

Browse files
authored
refactor(core): simplify OperationsInClassScanner interface (springwolf#1120)
Possible because Operation@operationId added. Continuation of 0eaa374
1 parent 4861d50 commit 399e2e1

16 files changed

+69
-85
lines changed

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/operations/DefaultOperationsService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ public class DefaultOperationsService implements OperationsService {
2727
*/
2828
@Override
2929
public Map<String, Operation> findOperations() {
30-
List<Map.Entry<String, Operation>> foundOperations = new ArrayList<>();
30+
List<Operation> foundOperations = new ArrayList<>();
3131

3232
for (OperationsScanner scanner : operationScanners) {
3333
try {
3434
Map<String, Operation> channels = scanner.scan();
35-
foundOperations.addAll(channels.entrySet());
35+
foundOperations.addAll(channels.values());
3636
} catch (Exception e) {
3737
log.error("An error was encountered during operation scanning with {}: {}", scanner, e.getMessage(), e);
3838
}

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/OperationMerger.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ private OperationMerger() {}
2525
* If an operation is null, the next non-null operation is used
2626
* Messages within operations are merged
2727
*
28-
* @param operationEntries Ordered pairs of operation name to Operation
28+
* @param operations Ordered pairs of operation name to Operation
2929
* @return A map of operationId to a single Operation
3030
*/
31-
public static Map<String, Operation> mergeOperations(List<Map.Entry<String, Operation>> operationEntries) {
31+
public static Map<String, Operation> mergeOperations(List<Operation> operations) {
3232
Map<String, Operation> mergedOperations = new HashMap<>();
3333

34-
for (Map.Entry<String, Operation> entry : operationEntries) {
35-
if (!mergedOperations.containsKey(entry.getKey())) {
36-
mergedOperations.put(entry.getKey(), entry.getValue());
34+
for (Operation operation : operations) {
35+
if (!mergedOperations.containsKey(operation.getOperationId())) {
36+
mergedOperations.put(operation.getOperationId(), operation);
3737
} else {
38-
Operation operation = mergeOperation(mergedOperations.get(entry.getKey()), entry.getValue());
39-
mergedOperations.put(entry.getKey(), operation);
38+
Operation mergedOperation = mergeOperation(mergedOperations.get(operation.getOperationId()), operation);
39+
mergedOperations.put(operation.getOperationId(), mergedOperation);
4040
}
4141
}
4242

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/OperationsInClassScanner.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33

44
import io.github.springwolf.asyncapi.v3.model.operation.Operation;
55

6-
import java.util.Map;
76
import java.util.stream.Stream;
87

98
public interface OperationsInClassScanner {
10-
Stream<Map.Entry<String, Operation>> scan(Class<?> clazz);
9+
Stream<Operation> scan(Class<?> clazz);
1110
}

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/OperationsInClassScannerAdapter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ public class OperationsInClassScannerAdapter implements OperationsScanner {
2121
public Map<String, Operation> scan() {
2222
Set<Class<?>> components = classScanner.scan();
2323

24-
List<Map.Entry<String, Operation>> operations = mapToOperations(components);
24+
List<Operation> operations = mapToOperations(components);
2525

2626
return OperationMerger.mergeOperations(operations);
2727
}
2828

29-
private List<Map.Entry<String, Operation>> mapToOperations(Set<Class<?>> components) {
29+
private List<Operation> mapToOperations(Set<Class<?>> components) {
3030
return components.stream().flatMap(classProcessor::scan).toList();
3131
}
3232
}

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/AsyncAnnotationClassLevelOperationsScanner.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import java.lang.annotation.Annotation;
1717
import java.lang.reflect.Method;
1818
import java.util.List;
19-
import java.util.Map;
2019
import java.util.Set;
2120
import java.util.stream.Collectors;
2221
import java.util.stream.Stream;
@@ -32,7 +31,7 @@ public class AsyncAnnotationClassLevelOperationsScanner<ClassAnnotation extends
3231
private final List<OperationCustomizer> customizers;
3332

3433
@Override
35-
public Stream<Map.Entry<String, Operation>> scan(Class<?> clazz) {
34+
public Stream<Operation> scan(Class<?> clazz) {
3635
Set<MethodAndAnnotation<ClassAnnotation>> methodAndAnnotation = AnnotationScannerUtil.findAnnotatedMethods(
3736
clazz, classAnnotationClass, AllMethods.class, (cl, m) -> {
3837
ClassAnnotation classAnnotation =
@@ -48,7 +47,7 @@ public Stream<Map.Entry<String, Operation>> scan(Class<?> clazz) {
4847
return mapClassToOperation(clazz, methodAndAnnotation);
4948
}
5049

51-
private Stream<Map.Entry<String, Operation>> mapClassToOperation(
50+
private Stream<Operation> mapClassToOperation(
5251
Class<?> component, Set<MethodAndAnnotation<ClassAnnotation>> annotatedMethods) {
5352
ClassAnnotation classAnnotation = AnnotationUtil.findFirstAnnotationOrThrow(classAnnotationClass, component);
5453
AsyncOperation asyncOperation = asyncAnnotationProvider.getAsyncOperation(classAnnotation);
@@ -58,6 +57,6 @@ private Stream<Map.Entry<String, Operation>> mapClassToOperation(
5857
Operation operation = asyncAnnotationOperationsService.buildOperation(asyncOperation, methods);
5958
annotatedMethods.forEach(
6059
method -> customizers.forEach(customizer -> customizer.customize(operation, method.method())));
61-
return Stream.of(Map.entry(operation.getOperationId(), operation));
60+
return Stream.of(operation);
6261
}
6362
}

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/AsyncAnnotationMethodLevelOperationsScanner.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
import java.lang.annotation.Annotation;
1515
import java.util.List;
16-
import java.util.Map;
1716
import java.util.Set;
1817
import java.util.stream.Stream;
1918

@@ -27,19 +26,18 @@ public class AsyncAnnotationMethodLevelOperationsScanner<MethodAnnotation extend
2726
private final List<OperationCustomizer> customizers;
2827

2928
@Override
30-
public Stream<Map.Entry<String, Operation>> scan(Class<?> clazz) {
29+
public Stream<Operation> scan(Class<?> clazz) {
3130
return AnnotationScannerUtil.findAnnotatedMethods(clazz, this.asyncAnnotationProvider.getAnnotation())
3231
.map(this::mapMethodToOperation);
3332
}
3433

35-
private Map.Entry<String, Operation> mapMethodToOperation(
36-
MethodAndAnnotation<MethodAnnotation> methodAndAnnotation) {
34+
private Operation mapMethodToOperation(MethodAndAnnotation<MethodAnnotation> methodAndAnnotation) {
3735
AsyncOperation operationAnnotation =
3836
this.asyncAnnotationProvider.getAsyncOperation(methodAndAnnotation.annotation());
3937

4038
Operation operation = asyncAnnotationOperationService.buildOperation(
4139
operationAnnotation, Set.of(methodAndAnnotation.method()));
4240
customizers.forEach(customizer -> customizer.customize(operation, methodAndAnnotation.method()));
43-
return Map.entry(operation.getOperationId(), operation);
41+
return operation;
4442
}
4543
}

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationClassLevelOperationsScanner.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import java.lang.annotation.Annotation;
1414
import java.lang.reflect.Method;
1515
import java.util.List;
16-
import java.util.Map;
1716
import java.util.Set;
1817
import java.util.stream.Collectors;
1918
import java.util.stream.Stream;
@@ -30,12 +29,12 @@ public class SpringAnnotationClassLevelOperationsScanner<
3029
private final List<OperationCustomizer> customizers;
3130

3231
@Override
33-
public Stream<Map.Entry<String, Operation>> scan(Class<?> clazz) {
32+
public Stream<Operation> scan(Class<?> clazz) {
3433
return AnnotationScannerUtil.findAnnotatedMethods(
3534
clazz, classAnnotationClass, methodAnnotationClass, this::mapClassToOperation);
3635
}
3736

38-
private Stream<Map.Entry<String, Operation>> mapClassToOperation(
37+
private Stream<Operation> mapClassToOperation(
3938
Class<?> component, Set<MethodAndAnnotation<MethodAnnotation>> annotatedMethods) {
4039
ClassAnnotation classAnnotation = AnnotationUtil.findFirstAnnotationOrThrow(classAnnotationClass, component);
4140

@@ -44,6 +43,6 @@ private Stream<Map.Entry<String, Operation>> mapClassToOperation(
4443
Operation operation = springAnnotationOperationsService.buildOperation(classAnnotation, component, methods);
4544
annotatedMethods.forEach(
4645
method -> customizers.forEach(customizer -> customizer.customize(operation, method.method())));
47-
return Stream.of(Map.entry(operation.getOperationId(), operation));
46+
return Stream.of(operation);
4847
}
4948
}

springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/operations/annotations/SpringAnnotationMethodLevelOperationsScanner.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
import java.lang.annotation.Annotation;
1717
import java.util.List;
18-
import java.util.Map;
1918
import java.util.stream.Stream;
2019

2120
@Slf4j
@@ -30,17 +29,17 @@ public class SpringAnnotationMethodLevelOperationsScanner<MethodAnnotation exten
3029
private final List<OperationCustomizer> customizers;
3130

3231
@Override
33-
public Stream<Map.Entry<String, Operation>> scan(Class<?> clazz) {
32+
public Stream<Operation> scan(Class<?> clazz) {
3433
return AnnotationScannerUtil.findAnnotatedMethods(clazz, methodAnnotationClass)
3534
.map(this::mapMethodToOperation);
3635
}
3736

38-
private Map.Entry<String, Operation> mapMethodToOperation(MethodAndAnnotation<MethodAnnotation> method) {
37+
private Operation mapMethodToOperation(MethodAndAnnotation<MethodAnnotation> method) {
3938
PayloadSchemaObject payloadSchema = payloadMethodParameterService.extractSchema(method.method());
4039
SchemaObject headerSchema = headerClassExtractor.extractHeader(method.method(), payloadSchema);
4140

4241
Operation operation = springAnnotationOperationService.buildOperation(method, payloadSchema, headerSchema);
4342
customizers.forEach(customizer -> customizer.customize(operation, method.method()));
44-
return Map.entry(operation.getOperationId(), operation);
43+
return operation;
4544
}
4645
}

springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/operations/DefaultOperationsServiceIntegrationTest.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ void getOperations() {
4646
static class SimpleOperationScanner implements OperationsScanner {
4747
@Override
4848
public Map<String, Operation> scan() {
49-
return Map.of(
50-
"foo",
51-
Operation.builder()
52-
.channel(ChannelReference.fromChannel("foo"))
53-
.action(OperationAction.RECEIVE)
54-
.build());
49+
Operation operation = Operation.builder()
50+
.operationId("foo")
51+
.channel(ChannelReference.fromChannel("foo"))
52+
.action(OperationAction.RECEIVE)
53+
.build();
54+
55+
return Map.of(operation.getOperationId(), operation);
5556
}
5657
}
5758

@@ -61,26 +62,28 @@ static class SameTopic {
6162
@Component
6263
static class SendOperationScanner implements OperationsScanner {
6364
static final Operation sentOperation = Operation.builder()
65+
.operationId("send")
6466
.channel(ChannelReference.fromChannel(topicName))
6567
.action(OperationAction.SEND)
6668
.build();
6769

6870
@Override
6971
public Map<String, Operation> scan() {
70-
return Map.of("send", sentOperation);
72+
return Map.of(sentOperation.getOperationId(), sentOperation);
7173
}
7274
}
7375

7476
@Component
7577
static class ReceiveOperationScanner implements OperationsScanner {
7678
static final Operation receiveOperation = Operation.builder()
79+
.operationId("receive")
7780
.channel(ChannelReference.fromChannel(topicName))
7881
.action(OperationAction.RECEIVE)
7982
.build();
8083

8184
@Override
8285
public Map<String, Operation> scan() {
83-
return Map.of("receive", receiveOperation);
86+
return Map.of(receiveOperation.getOperationId(), receiveOperation);
8487
}
8588
}
8689
}

springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/operations/OperationMergerTest.java

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ class OperationMergerTest {
2020
@Test
2121
void shouldNotMergeDifferentoperationIds() {
2222
// given
23-
String operationId1 = "operation1";
24-
String operationId2 = "operation2";
25-
Operation publisherOperation = Operation.builder().build();
26-
Operation subscriberOperation = Operation.builder().build();
23+
Operation publisherOperation =
24+
Operation.builder().operationId("operation1").build();
25+
Operation subscriberOperation =
26+
Operation.builder().operationId("operation2").build();
2727

2828
// when
29-
Map<String, Operation> mergedOperations = OperationMerger.mergeOperations(Arrays.asList(
30-
Map.entry(operationId1, publisherOperation), Map.entry(operationId2, subscriberOperation)));
29+
Map<String, Operation> mergedOperations =
30+
OperationMerger.mergeOperations(Arrays.asList(publisherOperation, subscriberOperation));
3131

3232
// then
3333
assertThat(mergedOperations).hasSize(2);
@@ -49,9 +49,8 @@ void shouldMergeEqualOperationIdsIntoOneOperation() {
4949
.build();
5050

5151
// when
52-
Map<String, Operation> mergedOperations = OperationMerger.mergeOperations(Arrays.asList(
53-
Map.entry(publishOperation.getOperationId(), publishOperation),
54-
Map.entry(subscribeOperation.getOperationId(), subscribeOperation)));
52+
Map<String, Operation> mergedOperations =
53+
OperationMerger.mergeOperations(Arrays.asList(publishOperation, subscribeOperation));
5554

5655
// then
5756
assertThat(mergedOperations).hasSize(1);
@@ -71,9 +70,8 @@ void shouldUseFirstOperationFound() {
7170
.build();
7271

7372
// when
74-
Map<String, Operation> mergedOperations = OperationMerger.mergeOperations(Arrays.asList(
75-
Map.entry(senderOperation.getOperationId(), senderOperation),
76-
Map.entry(receiverOperation.getOperationId(), receiverOperation)));
73+
Map<String, Operation> mergedOperations =
74+
OperationMerger.mergeOperations(Arrays.asList(senderOperation, receiverOperation));
7775

7876
// then
7977
assertThat(mergedOperations).hasSize(1).hasEntrySatisfying(operationId, it -> {
@@ -122,10 +120,8 @@ void shouldMergeDifferentMessageForSameOperation() {
122120
.build();
123121

124122
// when
125-
Map<String, Operation> mergedOperations = OperationMerger.mergeOperations(List.of(
126-
Map.entry(senderOperation1.getOperationId(), senderOperation1),
127-
Map.entry(senderOperation2.getOperationId(), senderOperation2),
128-
Map.entry(senderOperation3.getOperationId(), senderOperation3)));
123+
Map<String, Operation> mergedOperations =
124+
OperationMerger.mergeOperations(List.of(senderOperation1, senderOperation2, senderOperation3));
129125

130126
// then expectedMessage only includes message1 and message2.
131127
// Message3 is not included as it is identical in terms of payload type (Message#name) to message 2
@@ -174,17 +170,17 @@ void shouldUseOtherMessageIfFirstMessageIsMissingForOperations() {
174170
.build();
175171
Operation publishOperation1 = Operation.builder()
176172
.action(OperationAction.SEND)
177-
.title("publisher1")
173+
.operationId("publisher1")
178174
.build();
179175
Operation publishOperation2 = Operation.builder()
180176
.action(OperationAction.SEND)
181-
.title("publisher2")
177+
.operationId("publisher1")
182178
.messages(List.of(MessageReference.toChannelMessage(channelId, message2)))
183179
.build();
184180

185181
// when
186-
Map<String, Operation> mergedOperations = OperationMerger.mergeOperations(
187-
Arrays.asList(Map.entry("publisher1", publishOperation1), Map.entry("publisher1", publishOperation2)));
182+
Map<String, Operation> mergedOperations =
183+
OperationMerger.mergeOperations(Arrays.asList(publishOperation1, publishOperation2));
188184
// then expectedMessage message2
189185
var expectedMessage = MessageReference.toChannelMessage(channelId, message2);
190186

0 commit comments

Comments
 (0)