Skip to content

Commit

Permalink
feat(core): add override for info object on grouped api (#1093)
Browse files Browse the repository at this point in the history
* feat(core): add override for info object on grouped api

Co-authored-by: Timon Back <[email protected]>

* feat(core): map Info recursively

- extract mapper to AsyncApiInfoMapper
- fix mapping of termsOfService
- update kafka example

---------

Co-authored-by: Timon Back <[email protected]>
  • Loading branch information
sam0r040 and timonback authored Nov 29, 2024
1 parent 9667d6e commit d483fb0
Show file tree
Hide file tree
Showing 20 changed files with 317 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static io.github.springwolf.core.configuration.docket.AsyncApiInfoMapper.mapInfo;
import static io.github.springwolf.core.configuration.docket.AsyncApiInfoMapper.mergeInfo;

@Slf4j
@RequiredArgsConstructor
public class AsyncApiGroupService {
Expand All @@ -22,7 +25,11 @@ public class AsyncApiGroupService {

public Map<String, AsyncAPI> group(AsyncAPI asyncAPI) {
return getAsyncApiGroups()
.map(group -> Map.entry(group.getGroupName(), groupingService.groupAPI(asyncAPI, group)))
.map(group -> {
AsyncAPI groupedApi = groupingService.groupAPI(asyncAPI, group);
groupedApi.setInfo(mergeInfo(groupedApi.getInfo(), group.getGroupInfo()));
return Map.entry(group.getGroupName(), groupedApi);
})
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

Expand Down Expand Up @@ -55,6 +62,7 @@ private static AsyncApiGroup toGroupConfigAndValidate(SpringwolfConfigProperties

AsyncApiGroup asyncApiGroup = AsyncApiGroup.builder()
.groupName(groupName)
.groupInfo(mapInfo(group.getInfo()))
.operationActionsToKeep(group.getActionToMatch())
.channelNamesToKeep(channelNameToMatch)
.messageNamesToKeep(messageNameToMatch)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import io.github.springwolf.asyncapi.v3.model.channel.ChannelObject;
import io.github.springwolf.asyncapi.v3.model.channel.message.MessageObject;
import io.github.springwolf.asyncapi.v3.model.info.Info;
import io.github.springwolf.asyncapi.v3.model.operation.Operation;
import io.github.springwolf.asyncapi.v3.model.operation.OperationAction;
import lombok.AllArgsConstructor;
Expand All @@ -23,6 +24,9 @@
public class AsyncApiGroup {
private final String groupName;

@Builder.Default
private final Info groupInfo = Info.builder().build();

@Builder.Default
private final List<OperationAction> operationActionsToKeep = Collections.emptyList();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.springwolf.core.configuration.docket;

import io.github.springwolf.asyncapi.v3.model.info.Contact;
import io.github.springwolf.asyncapi.v3.model.info.Info;
import io.github.springwolf.asyncapi.v3.model.info.License;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;

import java.util.HashMap;
import java.util.Map;

public class AsyncApiInfoMapper {
public static Info mapInfo(SpringwolfConfigProperties.ConfigDocket.Info configDocketInfo) {
Info asyncapiInfo = Info.builder()
.version(configDocketInfo.getVersion())
.title(configDocketInfo.getTitle())
.description(configDocketInfo.getDescription())
.termsOfService(configDocketInfo.getTermsOfService())
.contact(configDocketInfo.getContact())
.license(configDocketInfo.getLicense())
.build();

// copy extension fields
if (configDocketInfo.getExtensionFields() != null) {
Map<String, Object> extFieldsMap = Map.copyOf(configDocketInfo.getExtensionFields());
asyncapiInfo.setExtensionFields(extFieldsMap);
}
return asyncapiInfo;
}

public static Info mergeInfo(Info original, Info updates) {
Info info = Info.builder()
.title(updates.getTitle() != null ? updates.getTitle() : original.getTitle())
.version(updates.getVersion() != null ? updates.getVersion() : original.getVersion())
.description(updates.getDescription() != null ? updates.getDescription() : original.getDescription())
.termsOfService(
updates.getTermsOfService() != null
? updates.getTermsOfService()
: original.getTermsOfService())
.contact(mergeContact(original.getContact(), updates.getContact()))
.license(mergeLicense(original.getLicense(), updates.getLicense()))
.tags(updates.getTags() != null ? updates.getTags() : original.getTags())
.build();

// copy extension fields
Map<String, Object> extFieldsMap = new HashMap<>();
if (original.getExtensionFields() != null) {
extFieldsMap.putAll(original.getExtensionFields());
}
if (updates.getExtensionFields() != null) {
extFieldsMap.putAll(updates.getExtensionFields());
}
if (!extFieldsMap.isEmpty()) {
info.setExtensionFields(extFieldsMap);
}

return info;
}

private static Contact mergeContact(Contact original, Contact updates) {
if (updates == null) {
return original;
}

return Contact.builder()
.name(updates.getName() != null ? updates.getName() : original.getName())
.url(updates.getUrl() != null ? updates.getUrl() : original.getUrl())
.email(updates.getEmail() != null ? updates.getEmail() : original.getEmail())
.build();
}

private static License mergeLicense(License original, License updates) {
if (updates == null) {
return original;
}

return License.builder()
.name(updates.getName() != null ? updates.getName() : original.getName())
.url(updates.getUrl() != null ? updates.getUrl() : original.getUrl())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import java.util.Map;

import static io.github.springwolf.core.configuration.docket.AsyncApiInfoMapper.mapInfo;
import static io.github.springwolf.core.configuration.properties.SpringwolfConfigConstants.SPRINGWOLF_CONFIG_PREFIX;

@Slf4j
Expand Down Expand Up @@ -63,21 +64,7 @@ private static Info buildInfo(@Nullable SpringwolfConfigProperties.ConfigDocket.
+ " is not set.");
}

Info asyncapiInfo = Info.builder()
.version(configDocketInfo.getVersion())
.title(configDocketInfo.getTitle())
.description(configDocketInfo.getDescription())
.contact(configDocketInfo.getContact())
.license(configDocketInfo.getLicense())
.build();

// copy extension fields from configDocketInfo to asyncapiInfo.
if (configDocketInfo.getExtensionFields() != null) {
Map<String, Object> extFieldsMap = Map.copyOf(configDocketInfo.getExtensionFields());
asyncapiInfo.setExtensionFields(extFieldsMap);
}

return asyncapiInfo;
return mapInfo(configDocketInfo);
}

private static Map<String, Server> buildServers(Map<String, Server> servers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ public static class ConfigDocket {

@Getter
@Setter
@EqualsAndHashCode
@ToString
public static class Info {

/**
Expand Down Expand Up @@ -196,7 +198,6 @@ public static class Info {
/**
* Extension properties for the Info block.
*/
@Nullable
private Map<String, String> extensionFields = Map.of("x-generator", "springwolf");
}

Expand All @@ -212,6 +213,13 @@ public static class Group {
*/
private String group = "";

/**
* Allows to override the info object with group specific information .
*
* @see Info
*/
private Info info = new Info();

/**
* The action to match for the group
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package io.github.springwolf.core.asyncapi.grouping;

import io.github.springwolf.asyncapi.v3.model.AsyncAPI;
import io.github.springwolf.asyncapi.v3.model.info.Info;
import io.github.springwolf.asyncapi.v3.model.operation.OperationAction;
import io.github.springwolf.core.configuration.docket.AsyncApiGroup;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
Expand Down Expand Up @@ -35,6 +36,7 @@ class AsyncApiGroupServiceTest {
@BeforeEach
void setUp() {
when(springwolfConfigProperties.getDocket()).thenReturn(configDocket);
when(groupedAsyncApi.getInfo()).thenReturn(new Info());
when(groupingService.groupAPI(eq(asyncAPI), any())).thenReturn(groupedAsyncApi);
}

Expand Down Expand Up @@ -118,13 +120,12 @@ void shouldGroupByAction() {
asyncApiGroupService.group(asyncAPI);

// then
verify(groupingService)
.groupAPI(
any(),
eq(AsyncApiGroup.builder()
.groupName("group1")
.operationActionsToKeep(actions)
.build()));
ArgumentCaptor<AsyncApiGroup> captor = ArgumentCaptor.forClass(AsyncApiGroup.class);
verify(groupingService).groupAPI(any(), captor.capture());

AsyncApiGroup capturedGroup = captor.getValue();
List<OperationAction> actualPattern = capturedGroup.getOperationActionsToKeep();
assertThat(actualPattern).isEqualTo(actions);
}

@Test
Expand All @@ -145,8 +146,6 @@ void shouldGroupByChannels() {
verify(groupingService).groupAPI(any(), captor.capture());

AsyncApiGroup capturedGroup = captor.getValue();
assertThat(capturedGroup.getGroupName()).isEqualTo("group1");

Pattern actualPattern = capturedGroup.getChannelNamesToKeep().get(0);
assertThat(actualPattern.pattern()).isEqualTo(channels.get(0));
}
Expand All @@ -169,9 +168,34 @@ void shouldGroupByMessage() {
verify(groupingService).groupAPI(any(), captor.capture());

AsyncApiGroup capturedGroup = captor.getValue();
assertThat(capturedGroup.getGroupName()).isEqualTo("group1");

Pattern actualPattern = capturedGroup.getMessageNamesToKeep().get(0);
assertThat(actualPattern.pattern()).isEqualTo(messages.get(0));
}

@Test
void shouldCustomizeInfoObject() {
// given
SpringwolfConfigProperties.ConfigDocket.Info groupInfo = new SpringwolfConfigProperties.ConfigDocket.Info();
groupInfo.setVersion("1.2.3");
groupInfo.setDescription("description-override");
SpringwolfConfigProperties.ConfigDocket.Group group = new SpringwolfConfigProperties.ConfigDocket.Group();
group.setGroup("group1");
group.setInfo(groupInfo);
when(configDocket.getGroupConfigs()).thenReturn(List.of(group));

Info originalInfo = new Info();
originalInfo.setDescription("description-original");
originalInfo.setTitle("title-original");
when(groupedAsyncApi.getInfo()).thenReturn(originalInfo);

// when
asyncApiGroupService.group(asyncAPI);

// then
ArgumentCaptor<Info> expectedInfoCaptor = ArgumentCaptor.forClass(Info.class);
verify(groupedAsyncApi).setInfo(expectedInfoCaptor.capture());
assertThat(expectedInfoCaptor.getValue().getVersion()).isEqualTo("1.2.3");
assertThat(expectedInfoCaptor.getValue().getDescription()).isEqualTo("description-override");
assertThat(expectedInfoCaptor.getValue().getTitle()).isEqualTo("title-original");
}
}
Loading

0 comments on commit d483fb0

Please sign in to comment.